actionpack 6.1.3.2 → 7.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +103 -387
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller/asset_paths.rb +1 -1
  6. data/lib/abstract_controller/base.rb +7 -21
  7. data/lib/abstract_controller/caching/fragments.rb +2 -2
  8. data/lib/abstract_controller/caching.rb +1 -1
  9. data/lib/abstract_controller/callbacks.rb +9 -8
  10. data/lib/abstract_controller/collector.rb +4 -2
  11. data/lib/abstract_controller/error.rb +1 -1
  12. data/lib/abstract_controller/helpers.rb +3 -2
  13. data/lib/abstract_controller/logger.rb +1 -1
  14. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  15. data/lib/abstract_controller/translation.rb +0 -2
  16. data/lib/abstract_controller/url_for.rb +4 -6
  17. data/lib/action_controller/api.rb +1 -1
  18. data/lib/action_controller/log_subscriber.rb +3 -1
  19. data/lib/action_controller/metal/conditional_get.rb +38 -1
  20. data/lib/action_controller/metal/content_security_policy.rb +1 -1
  21. data/lib/action_controller/metal/cookies.rb +1 -1
  22. data/lib/action_controller/metal/data_streaming.rb +5 -13
  23. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  24. data/lib/action_controller/metal/exceptions.rb +19 -30
  25. data/lib/action_controller/metal/flash.rb +6 -2
  26. data/lib/action_controller/metal/http_authentication.rb +15 -15
  27. data/lib/action_controller/metal/instrumentation.rb +55 -52
  28. data/lib/action_controller/metal/live.rb +52 -3
  29. data/lib/action_controller/metal/mime_responds.rb +3 -3
  30. data/lib/action_controller/metal/params_wrapper.rb +10 -9
  31. data/lib/action_controller/metal/permissions_policy.rb +1 -1
  32. data/lib/action_controller/metal/query_tags.rb +16 -0
  33. data/lib/action_controller/metal/redirecting.rb +50 -16
  34. data/lib/action_controller/metal/rendering.rb +7 -7
  35. data/lib/action_controller/metal/request_forgery_protection.rb +64 -20
  36. data/lib/action_controller/metal/rescue.rb +1 -1
  37. data/lib/action_controller/metal/streaming.rb +1 -3
  38. data/lib/action_controller/metal/strong_parameters.rb +24 -28
  39. data/lib/action_controller/metal/testing.rb +0 -2
  40. data/lib/action_controller/metal.rb +7 -10
  41. data/lib/action_controller/railtie.rb +42 -5
  42. data/lib/action_controller/test_case.rb +9 -2
  43. data/lib/action_controller.rb +2 -5
  44. data/lib/action_dispatch/http/cache.rb +18 -12
  45. data/lib/action_dispatch/http/content_security_policy.rb +39 -35
  46. data/lib/action_dispatch/http/filter_parameters.rb +5 -0
  47. data/lib/action_dispatch/http/mime_negotiation.rb +13 -3
  48. data/lib/action_dispatch/http/mime_type.rb +9 -11
  49. data/lib/action_dispatch/http/parameters.rb +4 -4
  50. data/lib/action_dispatch/http/permissions_policy.rb +1 -1
  51. data/lib/action_dispatch/http/request.rb +10 -19
  52. data/lib/action_dispatch/http/response.rb +3 -3
  53. data/lib/action_dispatch/http/url.rb +9 -10
  54. data/lib/action_dispatch/journey/formatter.rb +2 -2
  55. data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
  56. data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
  57. data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
  58. data/lib/action_dispatch/journey/nodes/node.rb +70 -5
  59. data/lib/action_dispatch/journey/path/pattern.rb +22 -13
  60. data/lib/action_dispatch/journey/route.rb +5 -12
  61. data/lib/action_dispatch/journey/router/utils.rb +2 -2
  62. data/lib/action_dispatch/journey/router.rb +1 -1
  63. data/lib/action_dispatch/journey/routes.rb +3 -3
  64. data/lib/action_dispatch/journey/visitors.rb +1 -1
  65. data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
  66. data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
  67. data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
  68. data/lib/action_dispatch/middleware/cookies.rb +7 -3
  69. data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
  70. data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
  71. data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
  72. data/lib/action_dispatch/middleware/flash.rb +9 -11
  73. data/lib/action_dispatch/middleware/host_authorization.rb +9 -17
  74. data/lib/action_dispatch/middleware/remote_ip.rb +16 -4
  75. data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
  76. data/lib/action_dispatch/middleware/show_exceptions.rb +7 -9
  77. data/lib/action_dispatch/middleware/stack.rb +27 -9
  78. data/lib/action_dispatch/middleware/static.rb +2 -5
  79. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
  80. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
  81. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
  82. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +3 -3
  83. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +1 -1
  84. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
  85. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
  86. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +1 -0
  87. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
  88. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
  89. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
  90. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  91. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  92. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
  93. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +5 -14
  94. data/lib/action_dispatch/railtie.rb +8 -2
  95. data/lib/action_dispatch/request/session.rb +43 -13
  96. data/lib/action_dispatch/routing/mapper.rb +44 -72
  97. data/lib/action_dispatch/routing/redirection.rb +0 -2
  98. data/lib/action_dispatch/routing/route_set.rb +9 -6
  99. data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
  100. data/lib/action_dispatch/routing/url_for.rb +1 -2
  101. data/lib/action_dispatch/routing.rb +2 -2
  102. data/lib/action_dispatch/system_test_case.rb +5 -5
  103. data/lib/action_dispatch/system_testing/driver.rb +24 -4
  104. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +10 -6
  105. data/lib/action_dispatch/testing/assertions.rb +2 -5
  106. data/lib/action_dispatch/testing/integration.rb +6 -8
  107. data/lib/action_dispatch/testing/test_process.rb +12 -9
  108. data/lib/action_dispatch.rb +1 -1
  109. data/lib/action_pack/gem_version.rb +4 -4
  110. data/lib/action_pack.rb +1 -1
  111. metadata +21 -20
@@ -24,14 +24,8 @@ module ActionController
24
24
  end
25
25
  end
26
26
 
27
- # Before processing, set the request formats in current controller formats.
28
- def process_action(*) #:nodoc:
29
- self.formats = request.formats.map(&:ref).compact
30
- super
31
- end
32
-
33
27
  # Check for double render errors and set the content_type after rendering.
34
- def render(*args) #:nodoc:
28
+ def render(*args) # :nodoc:
35
29
  raise ::AbstractController::DoubleRenderError if response_body
36
30
  super
37
31
  end
@@ -53,6 +47,12 @@ module ActionController
53
47
  end
54
48
 
55
49
  private
50
+ # Before processing, set the request formats in current controller formats.
51
+ def process_action(*) # :nodoc:
52
+ self.formats = request.formats.filter_map(&:ref)
53
+ super
54
+ end
55
+
56
56
  def _process_variant(options)
57
57
  if defined?(request) && !request.nil? && request.variant.present?
58
58
  options[:variant] = request.variant
@@ -4,11 +4,11 @@ require "rack/session/abstract/id"
4
4
  require "action_controller/metal/exceptions"
5
5
  require "active_support/security_utils"
6
6
 
7
- module ActionController #:nodoc:
8
- class InvalidAuthenticityToken < ActionControllerError #:nodoc:
7
+ module ActionController # :nodoc:
8
+ class InvalidAuthenticityToken < ActionControllerError # :nodoc:
9
9
  end
10
10
 
11
- class InvalidCrossOriginRequest < ActionControllerError #:nodoc:
11
+ class InvalidCrossOriginRequest < ActionControllerError # :nodoc:
12
12
  end
13
13
 
14
14
  # Controller actions are protected from Cross-Site Request Forgery (CSRF) attacks
@@ -57,6 +57,17 @@ module ActionController #:nodoc:
57
57
  module RequestForgeryProtection
58
58
  extend ActiveSupport::Concern
59
59
 
60
+ class DisabledSessionError < StandardError
61
+ MESSAGE = <<~EOS.squish
62
+ Request forgery protection requires a working session store but your application has sessions disabled.
63
+ You need to either disable request forgery protection, or configure a working session store.
64
+ EOS
65
+
66
+ def initialize(message = MESSAGE)
67
+ super
68
+ end
69
+ end
70
+
60
71
  include AbstractController::Helpers
61
72
  include AbstractController::Callbacks
62
73
 
@@ -90,6 +101,11 @@ module ActionController #:nodoc:
90
101
  config_accessor :default_protect_from_forgery
91
102
  self.default_protect_from_forgery = false
92
103
 
104
+ # Controls whether trying to use forgery protection without a working session store
105
+ # issues a warning or raises an error.
106
+ config_accessor :silence_disabled_session_errors
107
+ self.silence_disabled_session_errors = true
108
+
93
109
  # Controls whether URL-safe CSRF tokens are generated.
94
110
  config_accessor :urlsafe_csrf_tokens, instance_writer: false
95
111
  self.urlsafe_csrf_tokens = false
@@ -170,7 +186,7 @@ module ActionController #:nodoc:
170
186
  end
171
187
 
172
188
  private
173
- class NullSessionHash < Rack::Session::Abstract::SessionHash #:nodoc:
189
+ class NullSessionHash < Rack::Session::Abstract::SessionHash # :nodoc:
174
190
  def initialize(req)
175
191
  super(nil, req)
176
192
  @data = {}
@@ -183,9 +199,13 @@ module ActionController #:nodoc:
183
199
  def exists?
184
200
  true
185
201
  end
202
+
203
+ def enabled?
204
+ false
205
+ end
186
206
  end
187
207
 
188
- class NullCookieJar < ActionDispatch::Cookies::CookieJar #:nodoc:
208
+ class NullCookieJar < ActionDispatch::Cookies::CookieJar # :nodoc:
189
209
  def write(*)
190
210
  # nothing
191
211
  end
@@ -203,12 +223,14 @@ module ActionController #:nodoc:
203
223
  end
204
224
 
205
225
  class Exception
226
+ attr_accessor :warning_message
227
+
206
228
  def initialize(controller)
207
229
  @controller = controller
208
230
  end
209
231
 
210
232
  def handle_unverified_request
211
- raise ActionController::InvalidAuthenticityToken
233
+ raise ActionController::InvalidAuthenticityToken, warning_message
212
234
  end
213
235
  end
214
236
  end
@@ -228,22 +250,31 @@ module ActionController #:nodoc:
228
250
  mark_for_same_origin_verification!
229
251
 
230
252
  if !verified_request?
231
- if logger && log_warning_on_csrf_failure
232
- if valid_request_origin?
233
- logger.warn "Can't verify CSRF token authenticity."
234
- else
235
- logger.warn "HTTP Origin header (#{request.origin}) didn't match request.base_url (#{request.base_url})"
236
- end
237
- end
253
+ logger.warn unverified_request_warning_message if logger && log_warning_on_csrf_failure
254
+
238
255
  handle_unverified_request
239
256
  end
240
257
  end
241
258
 
242
259
  def handle_unverified_request # :doc:
243
- forgery_protection_strategy.new(self).handle_unverified_request
260
+ protection_strategy = forgery_protection_strategy.new(self)
261
+
262
+ if protection_strategy.respond_to?(:warning_message)
263
+ protection_strategy.warning_message = unverified_request_warning_message
264
+ end
265
+
266
+ protection_strategy.handle_unverified_request
267
+ end
268
+
269
+ def unverified_request_warning_message # :nodoc:
270
+ if valid_request_origin?
271
+ "Can't verify CSRF token authenticity."
272
+ else
273
+ "HTTP Origin header (#{request.origin}) didn't match request.base_url (#{request.base_url})"
274
+ end
244
275
  end
245
276
 
246
- #:nodoc:
277
+ # :nodoc:
247
278
  CROSS_ORIGIN_JAVASCRIPT_WARNING = "Security warning: an embedded " \
248
279
  "<script> tag on another site requested protected JavaScript. " \
249
280
  "If you know what you're doing, go ahead and disable forgery " \
@@ -303,15 +334,15 @@ module ActionController #:nodoc:
303
334
  [form_authenticity_param, request.x_csrf_token]
304
335
  end
305
336
 
306
- # Sets the token value for the current session.
307
- def form_authenticity_token(form_options: {})
337
+ # Creates the authenticity token for the current request.
338
+ def form_authenticity_token(form_options: {}) # :doc:
308
339
  masked_authenticity_token(session, form_options: form_options)
309
340
  end
310
341
 
311
342
  # Creates a masked version of the authenticity token that varies
312
343
  # on each request. The masking is used to mitigate SSL attacks
313
344
  # like BREACH.
314
- def masked_authenticity_token(session, form_options: {}) # :doc:
345
+ def masked_authenticity_token(session, form_options: {})
315
346
  action, method = form_options.values_at(:action, :method)
316
347
 
317
348
  raw_token = if per_form_csrf_tokens && action && method
@@ -438,7 +469,20 @@ module ActionController #:nodoc:
438
469
 
439
470
  # Checks if the controller allows forgery protection.
440
471
  def protect_against_forgery? # :doc:
441
- allow_forgery_protection
472
+ allow_forgery_protection && ensure_session_is_enabled!
473
+ end
474
+
475
+ def ensure_session_is_enabled!
476
+ if !session.respond_to?(:enabled?) || session.enabled?
477
+ true
478
+ else
479
+ if silence_disabled_session_errors
480
+ ActiveSupport::Deprecation.warn(DisabledSessionError::MESSAGE)
481
+ false
482
+ else
483
+ raise DisabledSessionError
484
+ end
485
+ end
442
486
  end
443
487
 
444
488
  NULL_ORIGIN_MESSAGE = <<~MSG
@@ -469,7 +513,7 @@ module ActionController #:nodoc:
469
513
 
470
514
  def generate_csrf_token # :nodoc:
471
515
  if urlsafe_csrf_tokens
472
- SecureRandom.urlsafe_base64(AUTHENTICITY_TOKEN_LENGTH, padding: false)
516
+ SecureRandom.urlsafe_base64(AUTHENTICITY_TOKEN_LENGTH)
473
517
  else
474
518
  SecureRandom.base64(AUTHENTICITY_TOKEN_LENGTH)
475
519
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ActionController #:nodoc:
3
+ module ActionController # :nodoc:
4
4
  # This module is responsible for providing +rescue_from+ helpers
5
5
  # to controllers and configuring when detailed exceptions must be
6
6
  # shown.
@@ -2,7 +2,7 @@
2
2
 
3
3
  require "rack/chunked"
4
4
 
5
- module ActionController #:nodoc:
5
+ module ActionController # :nodoc:
6
6
  # Allows views to be streamed back to the client as they are rendered.
7
7
  #
8
8
  # By default, Rails renders views by first rendering the template
@@ -193,8 +193,6 @@ module ActionController #:nodoc:
193
193
  # To be described.
194
194
  #
195
195
  module Streaming
196
- extend ActiveSupport::Concern
197
-
198
196
  private
199
197
  # Set proper cache control and transfer encoding when streaming
200
198
  def _process_options(options)
@@ -27,28 +27,13 @@ module ActionController
27
27
  super("param is missing or the value is empty: #{param}")
28
28
  end
29
29
 
30
- class Correction
31
- def initialize(error)
32
- @error = error
33
- end
34
-
35
- def corrections
36
- if @error.param && @error.keys
37
- maybe_these = @error.keys
30
+ if defined?(DidYouMean::Correctable) && defined?(DidYouMean::SpellChecker)
31
+ include DidYouMean::Correctable # :nodoc:
38
32
 
39
- maybe_these.sort_by { |n|
40
- DidYouMean::Jaro.distance(@error.param.to_s, n)
41
- }.reverse.first(4)
42
- else
43
- []
44
- end
33
+ def corrections # :nodoc:
34
+ @corrections ||= DidYouMean::SpellChecker.new(dictionary: keys).correct(param.to_s)
45
35
  end
46
36
  end
47
-
48
- # We may not have DYM, and DYM might not let us register error handlers
49
- if defined?(DidYouMean) && DidYouMean.respond_to?(:correct_error)
50
- DidYouMean.correct_error(self, Correction)
51
- end
52
37
  end
53
38
 
54
39
  # Raised when a supplied parameter is not expected and
@@ -106,11 +91,13 @@ module ActionController
106
91
  #
107
92
  # * +permit_all_parameters+ - If it's +true+, all the parameters will be
108
93
  # permitted by default. The default is +false+.
109
- # * +action_on_unpermitted_parameters+ - Allow to control the behavior when parameters
110
- # that are not explicitly permitted are found. The values can be +false+ to just filter them
111
- # out, <tt>:log</tt> to additionally write a message on the logger, or <tt>:raise</tt> to raise
112
- # ActionController::UnpermittedParameters exception. The default value is <tt>:log</tt>
113
- # in test and development environments, +false+ otherwise.
94
+ # * +action_on_unpermitted_parameters+ - Controls behavior when parameters that are not explicitly
95
+ # permitted are found. The default value is <tt>:log</tt> in test and development environments,
96
+ # +false+ otherwise. The values can be:
97
+ # * +false+ to take no action.
98
+ # * <tt>:log</tt> to emit an <tt>ActiveSupport::Notifications.instrument</tt> event on the
99
+ # <tt>unpermitted_parameters.action_controller</tt> topic and log at the DEBUG level.
100
+ # * <tt>:raise</tt> to raise a <tt>ActionController::UnpermittedParameters</tt> exception.
114
101
  #
115
102
  # Examples:
116
103
  #
@@ -277,8 +264,9 @@ module ActionController
277
264
  # params = ActionController::Parameters.new(name: "Francesco")
278
265
  # params.permitted? # => true
279
266
  # Person.new(params) # => #<Person id: nil, name: "Francesco">
280
- def initialize(parameters = {})
267
+ def initialize(parameters = {}, logging_context = {})
281
268
  @parameters = parameters.with_indifferent_access
269
+ @logging_context = logging_context
282
270
  @permitted = self.class.permit_all_parameters
283
271
  end
284
272
 
@@ -952,7 +940,7 @@ module ActionController
952
940
  def each_element(object, &block)
953
941
  case object
954
942
  when Array
955
- object.grep(Parameters).map { |el| yield el }.compact
943
+ object.grep(Parameters).filter_map(&block)
956
944
  when Parameters
957
945
  if object.nested_attributes?
958
946
  object.each_nested_attribute(&block)
@@ -968,7 +956,7 @@ module ActionController
968
956
  case self.class.action_on_unpermitted_parameters
969
957
  when :log
970
958
  name = "unpermitted_parameters.action_controller"
971
- ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys)
959
+ ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys, context: @logging_context)
972
960
  when :raise
973
961
  raise ActionController::UnpermittedParameters.new(unpermitted_keys)
974
962
  end
@@ -1184,7 +1172,15 @@ module ActionController
1184
1172
  # Returns a new ActionController::Parameters object that
1185
1173
  # has been instantiated with the <tt>request.parameters</tt>.
1186
1174
  def params
1187
- @_params ||= Parameters.new(request.parameters)
1175
+ @_params ||= begin
1176
+ context = {
1177
+ controller: self.class.name,
1178
+ action: action_name,
1179
+ request: request,
1180
+ params: request.filtered_parameters
1181
+ }
1182
+ Parameters.new(request.parameters, context)
1183
+ end
1188
1184
  end
1189
1185
 
1190
1186
  # Assigns the given +value+ to the +params+ hash. If +value+
@@ -2,8 +2,6 @@
2
2
 
3
3
  module ActionController
4
4
  module Testing
5
- extend ActiveSupport::Concern
6
-
7
5
  # Behavior specific to functional tests
8
6
  module Functional # :nodoc:
9
7
  def recycle!
@@ -2,8 +2,6 @@
2
2
 
3
3
  require "active_support/core_ext/array/extract_options"
4
4
  require "action_dispatch/middleware/stack"
5
- require "action_dispatch/http/request"
6
- require "action_dispatch/http/response"
7
5
 
8
6
  module ActionController
9
7
  # Extend ActionDispatch middleware stack to make it aware of options
@@ -13,8 +11,8 @@ module ActionController
13
11
  # use AuthenticationMiddleware, except: [:index, :show]
14
12
  # end
15
13
  #
16
- class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc:
17
- class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc:
14
+ class MiddlewareStack < ActionDispatch::MiddlewareStack # :nodoc:
15
+ class Middleware < ActionDispatch::MiddlewareStack::Middleware # :nodoc:
18
16
  def initialize(klass, args, actions, strategy, block)
19
17
  @actions = actions
20
18
  @strategy = strategy
@@ -184,7 +182,7 @@ module ActionController
184
182
  response_body || response.committed?
185
183
  end
186
184
 
187
- def dispatch(name, request, response) #:nodoc:
185
+ def dispatch(name, request, response) # :nodoc:
188
186
  set_request!(request)
189
187
  set_response!(response)
190
188
  process(name)
@@ -196,12 +194,12 @@ module ActionController
196
194
  @_response = response
197
195
  end
198
196
 
199
- def set_request!(request) #:nodoc:
197
+ def set_request!(request) # :nodoc:
200
198
  @_request = request
201
199
  @_request.controller_instance = self
202
200
  end
203
201
 
204
- def to_a #:nodoc:
202
+ def to_a # :nodoc:
205
203
  response.to_a
206
204
  end
207
205
 
@@ -219,10 +217,9 @@ module ActionController
219
217
  class << self
220
218
  # Pushes the given Rack middleware and its arguments to the bottom of the
221
219
  # middleware stack.
222
- def use(*args, &block)
223
- middleware_stack.use(*args, &block)
220
+ def use(...)
221
+ middleware_stack.use(...)
224
222
  end
225
- ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true)
226
223
  end
227
224
 
228
225
  # Alias for +middleware_stack+.
@@ -8,8 +8,10 @@ require "action_controller/railties/helpers"
8
8
  require "action_view/railtie"
9
9
 
10
10
  module ActionController
11
- class Railtie < Rails::Railtie #:nodoc:
11
+ class Railtie < Rails::Railtie # :nodoc:
12
12
  config.action_controller = ActiveSupport::OrderedOptions.new
13
+ config.action_controller.raise_on_open_redirects = false
14
+ config.action_controller.log_query_tags_around_actions = true
13
15
 
14
16
  config.eager_load_namespaces << ActionController
15
17
 
@@ -25,14 +27,19 @@ module ActionController
25
27
  options = app.config.action_controller
26
28
 
27
29
  ActiveSupport.on_load(:action_controller, run_once: true) do
28
- ActionController::Parameters.permit_all_parameters = options.delete(:permit_all_parameters) { false }
30
+ ActionController::Parameters.permit_all_parameters = options.permit_all_parameters || false
29
31
  if app.config.action_controller[:always_permitted_parameters]
30
32
  ActionController::Parameters.always_permitted_parameters =
31
- app.config.action_controller.delete(:always_permitted_parameters)
33
+ app.config.action_controller.always_permitted_parameters
32
34
  end
33
- ActionController::Parameters.action_on_unpermitted_parameters = options.delete(:action_on_unpermitted_parameters) do
34
- (Rails.env.test? || Rails.env.development?) ? :log : false
35
+
36
+ action_on_unpermitted_parameters = options.action_on_unpermitted_parameters
37
+
38
+ if action_on_unpermitted_parameters.nil?
39
+ action_on_unpermitted_parameters = (Rails.env.test? || Rails.env.development?) ? :log : false
35
40
  end
41
+
42
+ ActionController::Parameters.action_on_unpermitted_parameters = action_on_unpermitted_parameters
36
43
  end
37
44
  end
38
45
 
@@ -55,6 +62,14 @@ module ActionController
55
62
  extend ::AbstractController::Railties::RoutesHelpers.with(app.routes)
56
63
  extend ::ActionController::Railties::Helpers
57
64
 
65
+ # Configs used in other initializers
66
+ options = options.except(
67
+ :log_query_tags_around_actions,
68
+ :permit_all_parameters,
69
+ :action_on_unpermitted_parameters,
70
+ :always_permitted_parameters
71
+ )
72
+
58
73
  options.each do |k, v|
59
74
  k = "#{k}="
60
75
  if respond_to?(k)
@@ -85,5 +100,27 @@ module ActionController
85
100
  ActionController::Metal.descendants.each(&:action_methods) if config.eager_load
86
101
  end
87
102
  end
103
+
104
+ initializer "action_controller.query_log_tags" do |app|
105
+ query_logs_tags_enabled = app.config.respond_to?(:active_record) &&
106
+ app.config.active_record.query_log_tags_enabled &&
107
+ app.config.action_controller.log_query_tags_around_actions
108
+
109
+ if query_logs_tags_enabled
110
+ app.config.active_record.query_log_tags += [:controller, :action]
111
+
112
+ ActiveSupport.on_load(:action_controller) do
113
+ include ActionController::QueryTags
114
+ end
115
+
116
+ ActiveSupport.on_load(:active_record) do
117
+ ActiveRecord::QueryLogs.taggings.merge!(
118
+ controller: ->(context) { context[:controller].controller_name },
119
+ action: ->(context) { context[:controller].action_name },
120
+ namespaced_controller: ->(context) { context[:controller].class.name }
121
+ )
122
+ end
123
+ end
124
+ end
88
125
  end
89
126
  end