Update Mastodon to Rails 6.1 (#15910)

* Update devise-two-factor to unreleased fork for Rails 6 support

Update tests to match new `rotp` version.

* Update nsa gem to unreleased fork for Rails 6 support

* Update rails to 6.1.3 and rails-i18n to 6.0

* Update to unreleased fork of pluck_each for Ruby 6 support

* Run "rails app:update"

* Add missing ActiveStorage config file

* Use config.ssl_options instead of removed ApplicationController#force_ssl

Disabled force_ssl-related tests as they do not seem to be easily testable
anymore.

* Fix nonce directives by removing Rails 5 specific monkey-patching

* Fix fixture_file_upload deprecation warning

* Fix yield-based test failing with Rails 6

* Use Rails 6's index_with when possible

* Use ActiveRecord::Cache::Store#delete_multi from Rails 6

This will yield better performances when deleting an account

* Disable Rails 6.1's automatic preload link headers

Since Rails 6.1, ActionView adds preload links for javascript files
in the Links header per default.

In our case, that will bloat headers too much and potentially cause
issues with reverse proxies. Furhermore, we don't need those links,
as we already output them as HTML link tags.

* Switch to Rails 6.0 default config

* Switch to Rails 6.1 default config

* Do not include autoload paths in the load path
master
Claire 3 years ago committed by GitHub
parent 82556834cf
commit cbd0ee1d07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      Gemfile
  2. 181
      Gemfile.lock
  3. 6
      app/controllers/application_controller.rb
  4. 2
      app/lib/delivery_failure_tracker.rb
  5. 12
      app/lib/feed_manager.rb
  6. 2
      app/lib/settings/scoped_settings.rb
  7. 2
      app/models/concerns/account_interactions.rb
  8. 2
      app/models/report.rb
  9. 3
      app/services/delete_account_service.rb
  10. 4
      app/services/import_service.rb
  11. 16
      bin/setup
  12. 12
      bin/yarn
  13. 3
      config/application.rb
  14. 7
      config/environments/production.rb
  15. 10
      config/initializers/application_controller_renderer.rb
  16. 7
      config/initializers/backtrace_silencers.rb
  17. 12
      config/initializers/content_security_policy.rb
  18. 11
      config/initializers/permissions_policy.rb
  19. 8
      config/initializers/preload_link_headers.rb
  20. 0
      config/storage.yml
  21. 2
      lib/tasks/emojis.rake
  22. 4
      spec/controllers/api/v1/accounts/credentials_controller_spec.rb
  23. 10
      spec/controllers/api/v1/media_controller_spec.rb
  24. 14
      spec/controllers/application_controller_spec.rb
  25. 4
      spec/controllers/settings/imports_controller_spec.rb
  26. 4
      spec/controllers/settings/profiles_controller_spec.rb
  27. 2
      spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb
  28. 11
      spec/models/setting_spec.rb
  29. 2
      spec/models/user_spec.rb

@ -6,7 +6,7 @@ ruby '>= 2.5.0', '< 3.0.0'
gem 'pkg-config', '~> 1.4'
gem 'puma', '~> 5.2'
gem 'rails', '~> 5.2.4.5'
gem 'rails', '~> 6.1.3'
gem 'sprockets', '~> 3.7.2'
gem 'thor', '~> 1.1'
gem 'rack', '~> 2.2.3'
@ -34,7 +34,7 @@ gem 'iso-639'
gem 'chewy', '~> 5.2'
gem 'cld3', '~> 3.4.1'
gem 'devise', '~> 4.7'
gem 'devise-two-factor', '~> 3.1'
gem 'devise-two-factor', git: 'https://github.com/ClearlyClaire/devise-two-factor', ref: '594bb8a32e6f94df7e5ba7c9399eaf9ff25bac0d'
group :pam_authentication, optional: true do
gem 'devise_pam_authenticatable2', '~> 9.2'
@ -65,7 +65,7 @@ gem 'link_header', '~> 0.0'
gem 'mime-types', '~> 3.3.1', require: 'mime/types/columnar'
gem 'nilsimsa', git: 'https://github.com/witgo/nilsimsa', ref: 'fd184883048b922b176939f851338d0a4971a532'
gem 'nokogiri', '~> 1.11'
gem 'nsa', '~> 0.2'
gem 'nsa', git: 'https://github.com/Gargron/nsa', ref: 'd1079e0cdafdfed7f9f35478d13b9bdaa65965c0'
gem 'oj', '~> 3.11'
gem 'ox', '~> 2.14'
gem 'parslet'
@ -75,7 +75,7 @@ gem 'pundit', '~> 2.1'
gem 'premailer-rails'
gem 'rack-attack', '~> 6.5'
gem 'rack-cors', '~> 1.1', require: 'rack/cors'
gem 'rails-i18n', '~> 5.1'
gem 'rails-i18n', '~> 6.0'
gem 'rails-settings-cached', '~> 0.6'
gem 'redis', '~> 4.2', require: ['redis', 'redis/connection/hiredis']
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
@ -159,4 +159,4 @@ gem 'concurrent-ruby', require: false
gem 'connection_pool', require: false
gem 'xorcist', '~> 1.1'
gem 'pluck_each', '~> 0.1.3'
gem 'pluck_each', git: 'https://github.com/nsommer/pluck_each', ref: '73be0947c52fc54bf6d7085378db008358aac5eb'

@ -1,3 +1,26 @@
GIT
remote: https://github.com/ClearlyClaire/devise-two-factor
revision: 594bb8a32e6f94df7e5ba7c9399eaf9ff25bac0d
ref: 594bb8a32e6f94df7e5ba7c9399eaf9ff25bac0d
specs:
devise-two-factor (3.1.0)
activesupport (< 7.0)
attr_encrypted (>= 1.3, < 4, != 2)
devise
railties (< 7.0)
rotp (~> 6)
GIT
remote: https://github.com/Gargron/nsa
revision: d1079e0cdafdfed7f9f35478d13b9bdaa65965c0
ref: d1079e0cdafdfed7f9f35478d13b9bdaa65965c0
specs:
nsa (0.2.8)
activesupport (>= 4.2, < 7)
concurrent-ruby (~> 1.0, >= 1.0.2)
sidekiq (>= 3.5)
statsd-ruby (~> 1.4, >= 1.4.0)
GIT
remote: https://github.com/ianheggie/health_check
revision: 0b799ead604f900ed50685e9b2d469cd2befba5b
@ -6,6 +29,15 @@ GIT
health_check (4.0.0.pre)
rails (>= 4.0)
GIT
remote: https://github.com/nsommer/pluck_each
revision: 73be0947c52fc54bf6d7085378db008358aac5eb
ref: 73be0947c52fc54bf6d7085378db008358aac5eb
specs:
pluck_each (0.1.3)
activerecord (>= 6.1.0)
activesupport (>= 6.1.0)
GIT
remote: https://github.com/witgo/nilsimsa
revision: fd184883048b922b176939f851338d0a4971a532
@ -16,53 +48,71 @@ GIT
GEM
remote: https://rubygems.org/
specs:
actioncable (5.2.4.5)
actionpack (= 5.2.4.5)
actioncable (6.1.3)
actionpack (= 6.1.3)
activesupport (= 6.1.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailer (5.2.4.5)
actionpack (= 5.2.4.5)
actionview (= 5.2.4.5)
activejob (= 5.2.4.5)
actionmailbox (6.1.3)
actionpack (= 6.1.3)
activejob (= 6.1.3)
activerecord (= 6.1.3)
activestorage (= 6.1.3)
activesupport (= 6.1.3)
mail (>= 2.7.1)
actionmailer (6.1.3)
actionpack (= 6.1.3)
actionview (= 6.1.3)
activejob (= 6.1.3)
activesupport (= 6.1.3)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.2.4.5)
actionview (= 5.2.4.5)
activesupport (= 5.2.4.5)
rack (~> 2.0, >= 2.0.8)
actionpack (6.1.3)
actionview (= 6.1.3)
activesupport (= 6.1.3)
rack (~> 2.0, >= 2.0.9)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.2.4.5)
activesupport (= 5.2.4.5)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.1.3)
actionpack (= 6.1.3)
activerecord (= 6.1.3)
activestorage (= 6.1.3)
activesupport (= 6.1.3)
nokogiri (>= 1.8.5)
actionview (6.1.3)
activesupport (= 6.1.3)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
active_model_serializers (0.10.12)
actionpack (>= 4.1, < 6.2)
activemodel (>= 4.1, < 6.2)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
active_record_query_trace (1.8)
activejob (5.2.4.5)
activesupport (= 5.2.4.5)
activejob (6.1.3)
activesupport (= 6.1.3)
globalid (>= 0.3.6)
activemodel (5.2.4.5)
activesupport (= 5.2.4.5)
activerecord (5.2.4.5)
activemodel (= 5.2.4.5)
activesupport (= 5.2.4.5)
arel (>= 9.0)
activestorage (5.2.4.5)
actionpack (= 5.2.4.5)
activerecord (= 5.2.4.5)
activemodel (6.1.3)
activesupport (= 6.1.3)
activerecord (6.1.3)
activemodel (= 6.1.3)
activesupport (= 6.1.3)
activestorage (6.1.3)
actionpack (= 6.1.3)
activejob (= 6.1.3)
activerecord (= 6.1.3)
activesupport (= 6.1.3)
marcel (~> 0.3.1)
activesupport (5.2.4.5)
mimemagic (~> 0.3.2)
activesupport (6.1.3)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
tzinfo (~> 2.0)
zeitwerk (~> 2.3)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
airbrussh (1.4.0)
@ -71,7 +121,6 @@ GEM
annotate (3.1.1)
activerecord (>= 3.2, < 7.0)
rake (>= 10.4, < 14.0)
arel (9.0.0)
ast (2.4.2)
attr_encrypted (3.1.0)
encryptor (~> 3.0.0)
@ -175,12 +224,6 @@ GEM
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
devise-two-factor (3.1.0)
activesupport (< 6.1)
attr_encrypted (>= 1.3, < 4, != 2)
devise (~> 4.0)
railties (< 6.1)
rotp (~> 2.0)
devise_pam_authenticatable2 (9.2.0)
devise (>= 4.0.0)
rpam2 (~> 4.0)
@ -370,11 +413,6 @@ GEM
racc (~> 1.4)
nokogumbo (2.0.4)
nokogiri (~> 1.8, >= 1.8.4)
nsa (0.2.7)
activesupport (>= 4.2, < 6)
concurrent-ruby (~> 1.0, >= 1.0.2)
sidekiq (>= 3.5)
statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.11.3)
omniauth (1.9.1)
hashie (>= 3.4.6)
@ -414,9 +452,6 @@ GEM
pghero (2.8.0)
activerecord (>= 5)
pkg-config (1.4.5)
pluck_each (0.1.3)
activerecord (> 3.2.0)
activesupport (> 3.0.0)
posix-spawn (0.3.15)
premailer (1.14.2)
addressable
@ -450,18 +485,20 @@ GEM
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.2.4.5)
actioncable (= 5.2.4.5)
actionmailer (= 5.2.4.5)
actionpack (= 5.2.4.5)
actionview (= 5.2.4.5)
activejob (= 5.2.4.5)
activemodel (= 5.2.4.5)
activerecord (= 5.2.4.5)
activestorage (= 5.2.4.5)
activesupport (= 5.2.4.5)
bundler (>= 1.3.0)
railties (= 5.2.4.5)
rails (6.1.3)
actioncable (= 6.1.3)
actionmailbox (= 6.1.3)
actionmailer (= 6.1.3)
actionpack (= 6.1.3)
actiontext (= 6.1.3)
actionview (= 6.1.3)
activejob (= 6.1.3)
activemodel (= 6.1.3)
activerecord (= 6.1.3)
activestorage (= 6.1.3)
activesupport (= 6.1.3)
bundler (>= 1.15.0)
railties (= 6.1.3)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
@ -472,17 +509,17 @@ GEM
nokogiri (>= 1.6)
rails-html-sanitizer (1.3.0)
loofah (~> 2.3)
rails-i18n (5.1.3)
rails-i18n (6.0.0)
i18n (>= 0.7, < 2)
railties (>= 5.0, < 6)
railties (>= 6.0.0, < 7)
rails-settings-cached (0.6.6)
rails (>= 4.2.0)
railties (5.2.4.5)
actionpack (= 5.2.4.5)
activesupport (= 5.2.4.5)
railties (6.1.3)
actionpack (= 6.1.3)
activesupport (= 6.1.3)
method_source
rake (>= 0.8.7)
thor (>= 0.19.0, < 2.0)
thor (~> 1.0)
rainbow (3.0.0)
rake (13.0.3)
rdf (3.1.13)
@ -500,7 +537,7 @@ GEM
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.4)
rotp (2.1.2)
rotp (6.2.0)
rpam2 (4.0.2)
rqrcode (1.2.0)
chunky_png (~> 1.0)
@ -600,7 +637,7 @@ GEM
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
stackprof (0.2.16)
statsd-ruby (1.4.0)
statsd-ruby (1.5.0)
stoplight (2.2.1)
streamio-ffmpeg (3.0.2)
multi_json (~> 1.8)
@ -612,7 +649,6 @@ GEM
terrapin (0.6.0)
climate_control (>= 0.0.3, < 1.0)
thor (1.1.0)
thread_safe (0.3.6)
thwait (0.2.0)
e2mmap
tilt (2.0.10)
@ -632,8 +668,8 @@ GEM
twitter-text (3.1.0)
idn-ruby
unf (~> 0.1.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2021.1)
tzinfo (>= 1.0.0)
unf (0.1.4)
@ -672,6 +708,7 @@ GEM
xorcist (1.1.2)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.4.2)
PLATFORMS
ruby
@ -703,7 +740,7 @@ DEPENDENCIES
concurrent-ruby
connection_pool
devise (~> 4.7)
devise-two-factor (~> 3.1)
devise-two-factor!
devise_pam_authenticatable2 (~> 9.2)
discard (~> 1.2)
doorkeeper (~> 5.5)
@ -741,7 +778,7 @@ DEPENDENCIES
net-ldap (~> 0.17)
nilsimsa!
nokogiri (~> 1.11)
nsa (~> 0.2)
nsa!
oj (~> 3.11)
omniauth (~> 1.9)
omniauth-cas (~> 2.0)
@ -756,7 +793,7 @@ DEPENDENCIES
pg (~> 1.2)
pghero (~> 2.8)
pkg-config (~> 1.4)
pluck_each (~> 0.1.3)
pluck_each!
posix-spawn
premailer-rails
private_address_check (~> 0.5)
@ -767,9 +804,9 @@ DEPENDENCIES
rack (~> 2.2.3)
rack-attack (~> 6.5)
rack-cors (~> 1.1)
rails (~> 5.2.4.5)
rails (~> 6.1.3)
rails-controller-testing (~> 1.0)
rails-i18n (~> 5.1)
rails-i18n (~> 6.0)
rails-settings-cached (~> 0.6)
rdf-normalize (~> 0.4)
redis (~> 4.2)

@ -5,8 +5,6 @@ class ApplicationController < ActionController::Base
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
force_ssl if: :https_enabled?
include Localized
include UserTrackingConcern
include SessionTrackingConcern
@ -42,10 +40,6 @@ class ApplicationController < ActionController::Base
private
def https_enabled?
Rails.env.production? && !request.path.start_with?('/health') && !request.headers["Host"].end_with?(".onion")
end
def authorized_fetch_mode?
ENV['AUTHORIZED_FETCH'] == 'true' || Rails.configuration.x.whitelist_mode
end

@ -29,7 +29,7 @@ class DeliveryFailureTracker
class << self
def without_unavailable(urls)
unavailable_domains_map = Rails.cache.fetch('unavailable_domains') { UnavailableDomain.pluck(:domain).each_with_object({}) { |domain, hash| hash[domain] = true } }
unavailable_domains_map = Rails.cache.fetch('unavailable_domains') { UnavailableDomain.pluck(:domain).index_with(true) }
urls.reject do |url|
host = Addressable::URI.parse(url).normalized_host

@ -533,12 +533,12 @@ class FeedManager
arr
end
crutches[:following] = Follow.where(account_id: receiver_id, target_account_id: statuses.map(&:in_reply_to_account_id).compact).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
crutches[:hiding_reblogs] = Follow.where(account_id: receiver_id, target_account_id: statuses.map { |s| s.account_id if s.reblog? }.compact, show_reblogs: false).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
crutches[:blocking] = Block.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
crutches[:muting] = Mute.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
crutches[:domain_blocking] = AccountDomainBlock.where(account_id: receiver_id, domain: statuses.map { |s| s.reblog&.account&.domain }.compact).pluck(:domain).each_with_object({}) { |domain, mapping| mapping[domain] = true }
crutches[:blocked_by] = Block.where(target_account_id: receiver_id, account_id: statuses.map { |s| s.reblog&.account_id }.compact).pluck(:account_id).each_with_object({}) { |id, mapping| mapping[id] = true }
crutches[:following] = Follow.where(account_id: receiver_id, target_account_id: statuses.map(&:in_reply_to_account_id).compact).pluck(:target_account_id).index_with(true)
crutches[:hiding_reblogs] = Follow.where(account_id: receiver_id, target_account_id: statuses.map { |s| s.account_id if s.reblog? }.compact, show_reblogs: false).pluck(:target_account_id).index_with(true)
crutches[:blocking] = Block.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).index_with(true)
crutches[:muting] = Mute.where(account_id: receiver_id, target_account_id: check_for_blocks).pluck(:target_account_id).index_with(true)
crutches[:domain_blocking] = AccountDomainBlock.where(account_id: receiver_id, domain: statuses.map { |s| s.reblog&.account&.domain }.compact).pluck(:domain).index_with(true)
crutches[:blocked_by] = Block.where(target_account_id: receiver_id, account_id: statuses.map { |s| s.reblog&.account_id }.compact).pluck(:account_id).index_with(true)
crutches
end

@ -63,7 +63,7 @@ module Settings
class << self
def default_settings
defaulting = DEFAULTING_TO_UNSCOPED.each_with_object({}) { |k, h| h[k] = Setting[k] }
defaulting = DEFAULTING_TO_UNSCOPED.index_with { |k| Setting[k] }
Setting.default_settings.merge!(defaulting)
end
end

@ -67,7 +67,7 @@ module AccountInteractions
private
def follow_mapping(query, field)
query.pluck(field).each_with_object({}) { |id, mapping| mapping[id] = true }
query.pluck(field).index_with(true)
end
end

@ -32,7 +32,7 @@ class Report < ApplicationRecord
scope :unresolved, -> { where(action_taken: false) }
scope :resolved, -> { where(action_taken: true) }
scope :with_accounts, -> { includes([:account, :target_account, :action_taken_by_account, :assigned_account].each_with_object({}) { |k, h| h[k] = { user: [:invite_request, :invite] } }) }
scope :with_accounts, -> { includes([:account, :target_account, :action_taken_by_account, :assigned_account].index_with({ user: [:invite_request, :invite] })) }
validates :comment, length: { maximum: 1000 }

@ -188,8 +188,7 @@ class DeleteAccountService < BaseService
ids = favourites.pluck(:status_id)
StatusStat.where(status_id: ids).update_all('favourites_count = GREATEST(0, favourites_count - 1)')
Chewy.strategy.current.update(StatusesIndex::Status, ids) if Chewy.enabled?
# Rails.cache.delete_multi would be better, but we don't have it yet
ids.each { |id| Rails.cache.delete("statuses/#{id}") }
Rails.cache.delete_multi(ids.map { |id| "statuses/#{id}" })
favourites.delete_all
end
end

@ -45,7 +45,7 @@ class ImportService < BaseService
items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#domain'].strip }
if @import.overwrite?
presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true }
presence_hash = items.index_with(true)
@account.domain_blocks.find_each do |domain_block|
if presence_hash[domain_block.domain]
@ -96,7 +96,7 @@ class ImportService < BaseService
items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#uri'].strip }
if @import.overwrite?
presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true }
presence_hash = items.index_with(true)
@account.bookmarks.find_each do |bookmark|
if presence_hash[bookmark.status.uri]

@ -1,6 +1,5 @@
#!/usr/bin/env ruby
require 'fileutils'
include FileUtils
require "fileutils"
# path to your application root.
APP_ROOT = File.expand_path('..', __dir__)
@ -9,22 +8,25 @@ 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 set up or update your development environment automatically.
# This script is idempotent, so that you can run it at any time and get an expectable outcome.
# Add necessary setup steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
system!('yarn install')
# Install JavaScript dependencies
system! 'bin/yarn'
# 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'

@ -1,9 +1,15 @@
#!/usr/bin/env ruby
APP_ROOT = File.expand_path('..', __dir__)
Dir.chdir(APP_ROOT) do
begin
exec "yarnpkg", *ARGV
rescue Errno::ENOENT
yarn = ENV["PATH"].split(File::PATH_SEPARATOR).
select { |dir| File.expand_path(dir) != __dir__ }.
product(["yarn", "yarn.cmd", "yarn.ps1"]).
map { |dir, file| File.expand_path(file, dir) }.
find { |file| File.executable?(file) }
if yarn
exec yarn, *ARGV
else
$stderr.puts "Yarn executable was not detected in the system."
$stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
exit 1

@ -39,7 +39,8 @@ require_relative '../lib/mastodon/redis_config'
module Mastodon
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 5.2
config.load_defaults 6.1
config.add_autoload_paths_to_load_path = false
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers

@ -44,6 +44,13 @@ Rails.application.configure do
# Allow to specify public IP of reverse proxy if it's needed
config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split.map { |item| IPAddr.new(item) } if ENV['TRUSTED_PROXY_IP'].present?
config.force_ssl = true
config.ssl_options = {
redirect: {
exclude: -> request { request.path.start_with?('/health') || request.headers["Host"].end_with?('.onion') }
}
}
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = ENV.fetch('RAILS_LOG_LEVEL', 'info').to_sym

@ -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

@ -1,7 +1,8 @@
# Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) }
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"]

@ -49,17 +49,7 @@ end
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
# Monkey-patching Rails 5
module ActionDispatch
class ContentSecurityPolicy
def nonce_directive?(directive)
directive == 'style-src'
end
end
end
# Rails 6 would require the following instead:
# Rails.application.config.content_security_policy_nonce_directives = %w(style-src)
Rails.application.config.content_security_policy_nonce_directives = %w(style-src)
PgHero::HomeController.content_security_policy do |p|
p.script_src :self, :unsafe_inline, assets_host

@ -0,0 +1,11 @@
# 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"
# end

@ -0,0 +1,8 @@
# Since Rails 6.1, ActionView adds preload links for javascript files
# in the Links header per default.
# In our case, that will bloat headers too much and potentially cause
# issues with reverse proxies. Furhermore, we don't need those links,
# as we already output them as HTML link tags.
Rails.application.config.action_view.preload_links_header = false

@ -69,7 +69,7 @@ namespace :emojis do
end
end
existence_maps = grouped_codes.map { |c| c.map { |cc| [cc, File.exist?(Rails.root.join('public', 'emoji', codepoints_to_filename(cc) + '.svg'))] }.to_h }
existence_maps = grouped_codes.map { |c| c.index_with { |cc| File.exist?(Rails.root.join('public', 'emoji', codepoints_to_filename(cc) + '.svg')) } }
map = {}
existence_maps.each do |group|

@ -30,8 +30,8 @@ describe Api::V1::Accounts::CredentialsController do
patch :update, params: {
display_name: "Alice Isn't Dead",
note: "Hi!\n\nToot toot!",
avatar: fixture_file_upload('files/avatar.gif', 'image/gif'),
header: fixture_file_upload('files/attachment.jpg', 'image/jpeg'),
avatar: fixture_file_upload('avatar.gif', 'image/gif'),
header: fixture_file_upload('attachment.jpg', 'image/jpeg'),
source: {
privacy: 'unlisted',
sensitive: true,

@ -15,7 +15,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do
context 'when imagemagick cant identify the file type' do
before do
expect_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Errors::NotIdentifiedByImageMagickError)
post :create, params: { file: fixture_file_upload('files/attachment.jpg', 'image/jpeg') }
post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') }
end
it 'returns http 422' do
@ -26,7 +26,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do
context 'when there is a generic error' do
before do
expect_any_instance_of(Account).to receive_message_chain(:media_attachments, :create!).and_raise(Paperclip::Error)
post :create, params: { file: fixture_file_upload('files/attachment.jpg', 'image/jpeg') }
post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') }
end
it 'returns http 422' do
@ -37,7 +37,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do
context 'image/jpeg' do
before do
post :create, params: { file: fixture_file_upload('files/attachment.jpg', 'image/jpeg') }
post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') }
end
it 'returns http success' do
@ -59,7 +59,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do
context 'image/gif' do
before do
post :create, params: { file: fixture_file_upload('files/attachment.gif', 'image/gif') }
post :create, params: { file: fixture_file_upload('attachment.gif', 'image/gif') }
end
it 'returns http success' do
@ -81,7 +81,7 @@ RSpec.describe Api::V1::MediaController, type: :controller do
context 'video/webm' do
before do
post :create, params: { file: fixture_file_upload('files/attachment.webm', 'video/webm') }
post :create, params: { file: fixture_file_upload('attachment.webm', 'video/webm') }
end
it do

@ -42,20 +42,6 @@ describe ApplicationController, type: :controller do
include_examples 'respond_with_error', 422
end
it "does not force ssl if Rails.env.production? is not 'true'" do
routes.draw { get 'success' => 'anonymous#success' }
allow(Rails.env).to receive(:production?).and_return(false)
get 'success'
expect(response).to have_http_status(200)
end
it "forces ssl if Rails.env.production? is 'true'" do
routes.draw { get 'success' => 'anonymous#success' }
allow(Rails.env).to receive(:production?).and_return(true)
get 'success'
expect(response).to redirect_to('https://test.host/success')
end
describe 'helper_method :current_account' do
it 'returns nil if not signed in' do
expect(controller.view_context.current_account).to be_nil

@ -21,7 +21,7 @@ RSpec.describe Settings::ImportsController, type: :controller do
post :create, params: {
import: {
type: 'following',
data: fixture_file_upload('files/imports.txt')
data: fixture_file_upload('imports.txt')
}
}
@ -34,7 +34,7 @@ RSpec.describe Settings::ImportsController, type: :controller do
post :create, params: {
import: {
type: 'blocking',
data: fixture_file_upload('files/imports.txt')
data: fixture_file_upload('imports.txt')
}
}

@ -33,7 +33,7 @@ RSpec.describe Settings::ProfilesController, type: :controller do
account = Fabricate(:account, user: @user, display_name: 'AvatarTest')
expect(account.avatar.instance.avatar_file_name).to be_nil
put :update, params: { account: { avatar: fixture_file_upload('files/avatar.gif', 'image/gif') } }
put :update, params: { account: { avatar: fixture_file_upload('avatar.gif', 'image/gif') } }
expect(response).to redirect_to(settings_profile_path)
expect(account.reload.avatar.instance.avatar_file_name).not_to be_nil
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
@ -44,7 +44,7 @@ RSpec.describe Settings::ProfilesController, type: :controller do
it 'gives the user an error message' do
allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_async)
account = Fabricate(:account, user: @user, display_name: 'AvatarTest')
put :update, params: { account: { avatar: fixture_file_upload('files/4096x4097.png', 'image/png') } }
put :update, params: { account: { avatar: fixture_file_upload('4096x4097.png', 'image/png') } }
expect(response.body).to include('images are not supported')
end
end

@ -11,7 +11,7 @@ describe Settings::TwoFactorAuthentication::ConfirmationsController do
subject
expect(assigns(:confirmation)).to be_instance_of Form::TwoFactorConfirmation
expect(assigns(:provision_url)).to eq 'otpauth://totp/local-part@domain?secret=thisisasecretforthespecofnewview&issuer=cb6e6126.ngrok.io'
expect(assigns(:provision_url)).to eq 'otpauth://totp/cb6e6126.ngrok.io:local-part%40domain?secret=thisisasecretforthespecofnewview&issuer=cb6e6126.ngrok.io'
expect(assigns(:qrcode)).to be_instance_of RQRCode::QRCode
expect(response).to have_http_status(200)
expect(response).to render_template(:new)

@ -99,11 +99,12 @@ RSpec.describe Setting, type: :model do
end
it 'does not query the database' do
expect do |callback|
ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do
described_class[key]
end
end.not_to yield_control
callback = double
allow(callback).to receive(:call)
ActiveSupport::Notifications.subscribed callback, 'sql.active_record' do
described_class[key]
end
expect(callback).not_to have_received(:call)
end
it 'returns the cached value' do

@ -175,7 +175,7 @@ RSpec.describe User, type: :model do
user = Fabricate(:user)
ActiveJob::Base.queue_adapter = :test
expect { user.send_confirmation_instructions }.to have_enqueued_job(ActionMailer::DeliveryJob)
expect { user.send_confirmation_instructions }.to have_enqueued_job(ActionMailer::MailDeliveryJob)
end
end

Loading…
Cancel
Save