actionpack 6.1.7.5 → 7.0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (128) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +323 -399
  3. data/MIT-LICENSE +1 -0
  4. data/README.rdoc +4 -5
  5. data/lib/abstract_controller/asset_paths.rb +1 -1
  6. data/lib/abstract_controller/base.rb +13 -26
  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 +21 -7
  10. data/lib/abstract_controller/collector.rb +2 -2
  11. data/lib/abstract_controller/error.rb +1 -1
  12. data/lib/abstract_controller/helpers.rb +17 -12
  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/rendering.rb +9 -11
  16. data/lib/abstract_controller/translation.rb +27 -4
  17. data/lib/abstract_controller/url_for.rb +4 -6
  18. data/lib/action_controller/api.rb +7 -7
  19. data/lib/action_controller/base.rb +5 -4
  20. data/lib/action_controller/form_builder.rb +2 -2
  21. data/lib/action_controller/log_subscriber.rb +4 -3
  22. data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
  23. data/lib/action_controller/metal/conditional_get.rb +137 -102
  24. data/lib/action_controller/metal/content_security_policy.rb +36 -2
  25. data/lib/action_controller/metal/cookies.rb +1 -1
  26. data/lib/action_controller/metal/data_streaming.rb +23 -31
  27. data/lib/action_controller/metal/etag_with_flash.rb +1 -1
  28. data/lib/action_controller/metal/exceptions.rb +19 -30
  29. data/lib/action_controller/metal/flash.rb +6 -2
  30. data/lib/action_controller/metal/head.rb +1 -1
  31. data/lib/action_controller/metal/helpers.rb +2 -2
  32. data/lib/action_controller/metal/http_authentication.rb +66 -39
  33. data/lib/action_controller/metal/instrumentation.rb +57 -52
  34. data/lib/action_controller/metal/live.rb +43 -2
  35. data/lib/action_controller/metal/mime_responds.rb +3 -3
  36. data/lib/action_controller/metal/params_wrapper.rb +20 -11
  37. data/lib/action_controller/metal/permissions_policy.rb +19 -28
  38. data/lib/action_controller/metal/redirecting.rb +95 -22
  39. data/lib/action_controller/metal/renderers.rb +12 -13
  40. data/lib/action_controller/metal/rendering.rb +121 -9
  41. data/lib/action_controller/metal/request_forgery_protection.rb +83 -32
  42. data/lib/action_controller/metal/rescue.rb +5 -4
  43. data/lib/action_controller/metal/streaming.rb +7 -9
  44. data/lib/action_controller/metal/strong_parameters.rb +138 -115
  45. data/lib/action_controller/metal/testing.rb +9 -2
  46. data/lib/action_controller/metal/url_for.rb +3 -5
  47. data/lib/action_controller/metal.rb +10 -13
  48. data/lib/action_controller/railtie.rb +50 -6
  49. data/lib/action_controller/renderer.rb +1 -20
  50. data/lib/action_controller/test_case.rb +28 -7
  51. data/lib/action_controller.rb +2 -5
  52. data/lib/action_dispatch/http/cache.rb +20 -13
  53. data/lib/action_dispatch/http/content_security_policy.rb +113 -36
  54. data/lib/action_dispatch/http/filter_parameters.rb +4 -19
  55. data/lib/action_dispatch/http/headers.rb +1 -1
  56. data/lib/action_dispatch/http/mime_negotiation.rb +15 -5
  57. data/lib/action_dispatch/http/mime_type.rb +9 -11
  58. data/lib/action_dispatch/http/parameters.rb +5 -5
  59. data/lib/action_dispatch/http/permissions_policy.rb +17 -1
  60. data/lib/action_dispatch/http/request.rb +27 -37
  61. data/lib/action_dispatch/http/response.rb +3 -20
  62. data/lib/action_dispatch/http/upload.rb +13 -2
  63. data/lib/action_dispatch/http/url.rb +11 -19
  64. data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
  65. data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
  66. data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
  67. data/lib/action_dispatch/journey/nodes/node.rb +70 -5
  68. data/lib/action_dispatch/journey/path/pattern.rb +22 -13
  69. data/lib/action_dispatch/journey/route.rb +6 -13
  70. data/lib/action_dispatch/journey/router/utils.rb +2 -2
  71. data/lib/action_dispatch/journey/router.rb +1 -1
  72. data/lib/action_dispatch/journey/routes.rb +3 -3
  73. data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
  74. data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
  75. data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
  76. data/lib/action_dispatch/middleware/cookies.rb +20 -13
  77. data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
  78. data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
  79. data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
  80. data/lib/action_dispatch/middleware/executor.rb +3 -0
  81. data/lib/action_dispatch/middleware/flash.rb +17 -18
  82. data/lib/action_dispatch/middleware/host_authorization.rb +13 -17
  83. data/lib/action_dispatch/middleware/remote_ip.rb +20 -8
  84. data/lib/action_dispatch/middleware/request_id.rb +3 -3
  85. data/lib/action_dispatch/middleware/server_timing.rb +76 -0
  86. data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
  87. data/lib/action_dispatch/middleware/session/cookie_store.rb +9 -9
  88. data/lib/action_dispatch/middleware/show_exceptions.rb +17 -16
  89. data/lib/action_dispatch/middleware/stack.rb +27 -9
  90. data/lib/action_dispatch/middleware/static.rb +5 -9
  91. data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
  92. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
  93. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
  94. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +10 -5
  95. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +7 -3
  96. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
  97. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
  98. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
  99. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
  100. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
  101. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
  102. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  103. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
  104. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +22 -22
  105. data/lib/action_dispatch/railtie.rb +8 -2
  106. data/lib/action_dispatch/request/session.rb +43 -13
  107. data/lib/action_dispatch/routing/inspector.rb +1 -1
  108. data/lib/action_dispatch/routing/mapper.rb +82 -83
  109. data/lib/action_dispatch/routing/redirection.rb +5 -2
  110. data/lib/action_dispatch/routing/route_set.rb +17 -7
  111. data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
  112. data/lib/action_dispatch/routing/url_for.rb +24 -25
  113. data/lib/action_dispatch/routing.rb +5 -6
  114. data/lib/action_dispatch/system_test_case.rb +5 -5
  115. data/lib/action_dispatch/system_testing/browser.rb +3 -13
  116. data/lib/action_dispatch/system_testing/driver.rb +34 -10
  117. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +11 -7
  118. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +0 -8
  119. data/lib/action_dispatch/testing/assertions/response.rb +1 -1
  120. data/lib/action_dispatch/testing/assertions/routing.rb +3 -2
  121. data/lib/action_dispatch/testing/assertions.rb +2 -5
  122. data/lib/action_dispatch/testing/integration.rb +6 -8
  123. data/lib/action_dispatch/testing/test_process.rb +3 -29
  124. data/lib/action_dispatch/testing/test_response.rb +20 -2
  125. data/lib/action_dispatch.rb +1 -0
  126. data/lib/action_pack/gem_version.rb +5 -5
  127. data/lib/action_pack/version.rb +1 -1
  128. metadata +16 -15
@@ -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
@@ -96,7 +81,7 @@ module ActionController
96
81
  # })
97
82
  #
98
83
  # permitted = params.require(:person).permit(:name, :age)
99
- # permitted # => <ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
84
+ # permitted # => #<ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
100
85
  # permitted.permitted? # => true
101
86
  #
102
87
  # Person.first.update!(permitted)
@@ -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 an ActionController::UnpermittedParameters exception.
114
101
  #
115
102
  # Examples:
116
103
  #
@@ -124,7 +111,7 @@ module ActionController
124
111
  #
125
112
  # params = ActionController::Parameters.new(a: "123", b: "456")
126
113
  # params.permit(:c)
127
- # # => <ActionController::Parameters {} permitted: true>
114
+ # # => #<ActionController::Parameters {} permitted: true>
128
115
  #
129
116
  # ActionController::Parameters.action_on_unpermitted_parameters = :raise
130
117
  #
@@ -159,7 +146,7 @@ module ActionController
159
146
  # :method: each_key
160
147
  #
161
148
  # :call-seq:
162
- # each_key()
149
+ # each_key(&block)
163
150
  #
164
151
  # Calls block once for each key in the parameters, passing the key.
165
152
  # If no block is given, an enumerator is returned instead.
@@ -172,14 +159,6 @@ module ActionController
172
159
  #
173
160
  # Returns true if the parameters have no key/value pairs.
174
161
 
175
- ##
176
- # :method: has_key?
177
- #
178
- # :call-seq:
179
- # has_key?(key)
180
- #
181
- # Returns true if the given key is present in the parameters.
182
-
183
162
  ##
184
163
  # :method: has_value?
185
164
  #
@@ -196,22 +175,6 @@ module ActionController
196
175
  #
197
176
  # Returns true if the given key is present in the parameters.
198
177
 
199
- ##
200
- # :method: key?
201
- #
202
- # :call-seq:
203
- # key?(key)
204
- #
205
- # Returns true if the given key is present in the parameters.
206
-
207
- ##
208
- # :method: member?
209
- #
210
- # :call-seq:
211
- # member?(key)
212
- #
213
- # Returns true if the given key is present in the parameters.
214
-
215
178
  ##
216
179
  # :method: keys
217
180
  #
@@ -243,13 +206,17 @@ module ActionController
243
206
  # values()
244
207
  #
245
208
  # Returns a new array of the values of the parameters.
246
- delegate :keys, :key?, :has_key?, :member?, :values, :has_value?, :value?, :empty?, :include?,
209
+ delegate :keys, :values, :has_value?, :value?, :empty?, :include?,
247
210
  :as_json, :to_s, :each_key, to: :@parameters
248
211
 
212
+ alias_method :has_key?, :include?
213
+ alias_method :key?, :include?
214
+ alias_method :member?, :include?
215
+
249
216
  # By default, never raise an UnpermittedParameters exception if these
250
217
  # params are present. The default includes both 'controller' and 'action'
251
218
  # because they are added by Rails and should be of no concern. One way
252
- # to change these is to specify `always_permitted_parameters` in your
219
+ # to change these is to specify +always_permitted_parameters+ in your
253
220
  # config. For instance:
254
221
  #
255
222
  # config.action_controller.always_permitted_parameters = %w( controller action format )
@@ -261,7 +228,7 @@ module ActionController
261
228
  end
262
229
  end
263
230
 
264
- # Returns a new instance of <tt>ActionController::Parameters</tt>.
231
+ # Returns a new <tt>ActionController::Parameters</tt> instance.
265
232
  # Also, sets the +permitted+ attribute to the default value of
266
233
  # <tt>ActionController::Parameters.permit_all_parameters</tt>.
267
234
  #
@@ -277,8 +244,9 @@ module ActionController
277
244
  # params = ActionController::Parameters.new(name: "Francesco")
278
245
  # params.permitted? # => true
279
246
  # Person.new(params) # => #<Person id: nil, name: "Francesco">
280
- def initialize(parameters = {})
247
+ def initialize(parameters = {}, logging_context = {})
281
248
  @parameters = parameters.with_indifferent_access
249
+ @logging_context = logging_context
282
250
  @permitted = self.class.permit_all_parameters
283
251
  end
284
252
 
@@ -291,13 +259,18 @@ module ActionController
291
259
  @parameters == other
292
260
  end
293
261
  end
294
- alias eql? ==
262
+
263
+ def eql?(other)
264
+ self.class == other.class &&
265
+ permitted? == other.permitted? &&
266
+ parameters.eql?(other.parameters)
267
+ end
295
268
 
296
269
  def hash
297
- [@parameters.hash, @permitted].hash
270
+ [self.class, @parameters, @permitted].hash
298
271
  end
299
272
 
300
- # Returns a safe <tt>ActiveSupport::HashWithIndifferentAccess</tt>
273
+ # Returns a safe ActiveSupport::HashWithIndifferentAccess
301
274
  # representation of the parameters with all unpermitted keys removed.
302
275
  #
303
276
  # params = ActionController::Parameters.new({
@@ -357,18 +330,15 @@ module ActionController
357
330
  # safe_params.to_query("user")
358
331
  # # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
359
332
  #
360
- # The string pairs "key=value" that conform the query string
333
+ # The string pairs <tt>"key=value"</tt> that conform the query string
361
334
  # are sorted lexicographically in ascending order.
362
- #
363
- # This method is also aliased as +to_param+.
364
335
  def to_query(*args)
365
336
  to_h.to_query(*args)
366
337
  end
367
338
  alias_method :to_param, :to_query
368
339
 
369
- # Returns an unsafe, unfiltered
370
- # <tt>ActiveSupport::HashWithIndifferentAccess</tt> representation of the
371
- # parameters.
340
+ # Returns an unsafe, unfiltered ActiveSupport::HashWithIndifferentAccess
341
+ # representation of the parameters.
372
342
  #
373
343
  # params = ActionController::Parameters.new({
374
344
  # name: "Senjougahara Hitagi",
@@ -408,7 +378,7 @@ module ActionController
408
378
  # looping in the common use case permit + mass-assignment. Defined in a
409
379
  # method to instantiate it only if needed.
410
380
  #
411
- # Testing membership still loops, but it's going to be faster than our own
381
+ # \Testing membership still loops, but it's going to be faster than our own
412
382
  # loop that converts values. Also, we are not going to build a new array
413
383
  # object per fetch.
414
384
  def converted_arrays
@@ -454,9 +424,9 @@ module ActionController
454
424
  # either present or the singleton +false+, returns said value:
455
425
  #
456
426
  # ActionController::Parameters.new(person: { name: "Francesco" }).require(:person)
457
- # # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
427
+ # # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
458
428
  #
459
- # Otherwise raises <tt>ActionController::ParameterMissing</tt>:
429
+ # Otherwise raises ActionController::ParameterMissing:
460
430
  #
461
431
  # ActionController::Parameters.new.require(:person)
462
432
  # # ActionController::ParameterMissing: param is missing or the value is empty: person
@@ -508,7 +478,6 @@ module ActionController
508
478
  end
509
479
  end
510
480
 
511
- # Alias of #require.
512
481
  alias :required :require
513
482
 
514
483
  # Returns a new <tt>ActionController::Parameters</tt> instance that
@@ -530,7 +499,7 @@ module ActionController
530
499
  # +:name+ passes if it is a key of +params+ whose associated value is of type
531
500
  # +String+, +Symbol+, +NilClass+, +Numeric+, +TrueClass+, +FalseClass+,
532
501
  # +Date+, +Time+, +DateTime+, +StringIO+, +IO+,
533
- # +ActionDispatch::Http::UploadedFile+ or +Rack::Test::UploadedFile+.
502
+ # ActionDispatch::Http::UploadedFile or +Rack::Test::UploadedFile+.
534
503
  # Otherwise, the key +:name+ is filtered out.
535
504
  #
536
505
  # You may declare that the parameter should be an array of permitted scalars
@@ -582,13 +551,48 @@ module ActionController
582
551
  # })
583
552
  #
584
553
  # params.require(:person).permit(:contact)
585
- # # => <ActionController::Parameters {} permitted: true>
554
+ # # => #<ActionController::Parameters {} permitted: true>
586
555
  #
587
556
  # params.require(:person).permit(contact: :phone)
588
- # # => <ActionController::Parameters {"contact"=><ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
557
+ # # => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
589
558
  #
590
559
  # params.require(:person).permit(contact: [ :email, :phone ])
591
- # # => <ActionController::Parameters {"contact"=><ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
560
+ # # => #<ActionController::Parameters {"contact"=>#<ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
561
+ #
562
+ # If your parameters specify multiple parameters indexed by a number,
563
+ # you can permit each set of parameters under the numeric key to be the same using the same syntax as permitting a single item.
564
+ #
565
+ # params = ActionController::Parameters.new({
566
+ # person: {
567
+ # '0': {
568
+ # email: "none@test.com",
569
+ # phone: "555-1234"
570
+ # },
571
+ # '1': {
572
+ # email: "nothing@test.com",
573
+ # phone: "555-6789"
574
+ # },
575
+ # }
576
+ # })
577
+ # params.permit(person: [:email]).to_h
578
+ # # => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"email"=>"nothing@test.com"}}}
579
+ #
580
+ # If you want to specify what keys you want from each numeric key, you can instead specify each one individually
581
+ #
582
+ # params = ActionController::Parameters.new({
583
+ # person: {
584
+ # '0': {
585
+ # email: "none@test.com",
586
+ # phone: "555-1234"
587
+ # },
588
+ # '1': {
589
+ # email: "nothing@test.com",
590
+ # phone: "555-6789"
591
+ # },
592
+ # }
593
+ # })
594
+ # params.permit(person: { '0': [:email], '1': [:phone]}).to_h
595
+ # # => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"phone"=>"555-6789"}}}
592
596
  def permit(*filters)
593
597
  params = self.class.new
594
598
 
@@ -610,29 +614,29 @@ module ActionController
610
614
  # returns +nil+.
611
615
  #
612
616
  # params = ActionController::Parameters.new(person: { name: "Francesco" })
613
- # params[:person] # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
617
+ # params[:person] # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
614
618
  # params[:none] # => nil
615
619
  def [](key)
616
620
  convert_hashes_to_parameters(key, @parameters[key])
617
621
  end
618
622
 
619
623
  # Assigns a value to a given +key+. The given key may still get filtered out
620
- # when +permit+ is called.
624
+ # when #permit is called.
621
625
  def []=(key, value)
622
626
  @parameters[key] = value
623
627
  end
624
628
 
625
629
  # Returns a parameter for the given +key+. If the +key+
626
630
  # can't be found, there are several options: With no other arguments,
627
- # it will raise an <tt>ActionController::ParameterMissing</tt> error;
631
+ # it will raise an ActionController::ParameterMissing error;
628
632
  # if a second argument is given, then that is returned (converted to an
629
- # instance of ActionController::Parameters if possible); if a block
633
+ # instance of +ActionController::Parameters+ if possible); if a block
630
634
  # is given, then that will be run and its result returned.
631
635
  #
632
636
  # params = ActionController::Parameters.new(person: { name: "Francesco" })
633
- # params.fetch(:person) # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
637
+ # params.fetch(:person) # => #<ActionController::Parameters {"name"=>"Francesco"} permitted: false>
634
638
  # params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none
635
- # params.fetch(:none, {}) # => <ActionController::Parameters {} permitted: false>
639
+ # params.fetch(:none, {}) # => #<ActionController::Parameters {} permitted: false>
636
640
  # params.fetch(:none, "Francesco") # => "Francesco"
637
641
  # params.fetch(:none) { "Francesco" } # => "Francesco"
638
642
  def fetch(key, *args)
@@ -666,13 +670,13 @@ module ActionController
666
670
  # don't exist, returns an empty hash.
667
671
  #
668
672
  # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
669
- # params.slice(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
670
- # params.slice(:d) # => <ActionController::Parameters {} permitted: false>
673
+ # params.slice(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
674
+ # params.slice(:d) # => #<ActionController::Parameters {} permitted: false>
671
675
  def slice(*keys)
672
676
  new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
673
677
  end
674
678
 
675
- # Returns current <tt>ActionController::Parameters</tt> instance which
679
+ # Returns the current <tt>ActionController::Parameters</tt> instance which
676
680
  # contains only the given +keys+.
677
681
  def slice!(*keys)
678
682
  @parameters.slice!(*keys)
@@ -683,8 +687,8 @@ module ActionController
683
687
  # filters out the given +keys+.
684
688
  #
685
689
  # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
686
- # params.except(:a, :b) # => <ActionController::Parameters {"c"=>3} permitted: false>
687
- # params.except(:d) # => <ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
690
+ # params.except(:a, :b) # => #<ActionController::Parameters {"c"=>3} permitted: false>
691
+ # params.except(:d) # => #<ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
688
692
  def except(*keys)
689
693
  new_instance_with_inherited_permitted_status(@parameters.except(*keys))
690
694
  end
@@ -692,18 +696,18 @@ module ActionController
692
696
  # Removes and returns the key/value pairs matching the given keys.
693
697
  #
694
698
  # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
695
- # params.extract!(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
696
- # params # => <ActionController::Parameters {"c"=>3} permitted: false>
699
+ # params.extract!(:a, :b) # => #<ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
700
+ # params # => #<ActionController::Parameters {"c"=>3} permitted: false>
697
701
  def extract!(*keys)
698
702
  new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
699
703
  end
700
704
 
701
- # Returns a new <tt>ActionController::Parameters</tt> with the results of
705
+ # Returns a new <tt>ActionController::Parameters</tt> instance with the results of
702
706
  # running +block+ once for every value. The keys are unchanged.
703
707
  #
704
708
  # params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
705
709
  # params.transform_values { |x| x * 2 }
706
- # # => <ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
710
+ # # => #<ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
707
711
  def transform_values
708
712
  return to_enum(:transform_values) unless block_given?
709
713
  new_instance_with_inherited_permitted_status(
@@ -745,9 +749,9 @@ module ActionController
745
749
  )
746
750
  end
747
751
 
748
- # Returns the <tt>ActionController::Parameters</tt> instance changing its keys.
749
- # This includes the keys from the root hash and from all nested hashes and arrays.
750
- # The values are unchanged.
752
+ # Returns the same <tt>ActionController::Parameters</tt> instance with
753
+ # changed keys. This includes the keys from the root hash and from all
754
+ # nested hashes and arrays. The values are unchanged.
751
755
  def deep_transform_keys!(&block)
752
756
  @parameters.deep_transform_keys!(&block)
753
757
  self
@@ -755,13 +759,13 @@ module ActionController
755
759
 
756
760
  # Deletes a key-value pair from +Parameters+ and returns the value. If
757
761
  # +key+ is not found, returns +nil+ (or, with optional code block, yields
758
- # +key+ and returns the result). Cf. +#extract!+, which returns the
759
- # corresponding +ActionController::Parameters+ object.
762
+ # +key+ and returns the result). This method is similar to #extract!, which
763
+ # returns the corresponding +ActionController::Parameters+ object.
760
764
  def delete(key, &block)
761
765
  convert_value_to_parameters(@parameters.delete(key, &block))
762
766
  end
763
767
 
764
- # Returns a new instance of <tt>ActionController::Parameters</tt> with only
768
+ # Returns a new <tt>ActionController::Parameters</tt> instance with only
765
769
  # items that the block evaluates to true.
766
770
  def select(&block)
767
771
  new_instance_with_inherited_permitted_status(@parameters.select(&block))
@@ -774,7 +778,7 @@ module ActionController
774
778
  end
775
779
  alias_method :keep_if, :select!
776
780
 
777
- # Returns a new instance of <tt>ActionController::Parameters</tt> with items
781
+ # Returns a new <tt>ActionController::Parameters</tt> instance with items
778
782
  # that the block evaluates to true removed.
779
783
  def reject(&block)
780
784
  new_instance_with_inherited_permitted_status(@parameters.reject(&block))
@@ -787,7 +791,7 @@ module ActionController
787
791
  end
788
792
  alias_method :delete_if, :reject!
789
793
 
790
- # Returns a new instance of <tt>ActionController::Parameters</tt> with +nil+ values removed.
794
+ # Returns a new <tt>ActionController::Parameters</tt> instance with +nil+ values removed.
791
795
  def compact
792
796
  new_instance_with_inherited_permitted_status(@parameters.compact)
793
797
  end
@@ -797,7 +801,7 @@ module ActionController
797
801
  self if @parameters.compact!
798
802
  end
799
803
 
800
- # Returns a new instance of <tt>ActionController::Parameters</tt> without the blank values.
804
+ # Returns a new <tt>ActionController::Parameters</tt> instance without the blank values.
801
805
  # Uses Object#blank? for determining if a value is blank.
802
806
  def compact_blank
803
807
  reject { |_k, v| v.blank? }
@@ -815,7 +819,7 @@ module ActionController
815
819
  convert_value_to_parameters(@parameters.values_at(*keys))
816
820
  end
817
821
 
818
- # Returns a new <tt>ActionController::Parameters</tt> with all keys from
822
+ # Returns a new <tt>ActionController::Parameters</tt> instance with all keys from
819
823
  # +other_hash+ merged into current hash.
820
824
  def merge(other_hash)
821
825
  new_instance_with_inherited_permitted_status(
@@ -823,15 +827,15 @@ module ActionController
823
827
  )
824
828
  end
825
829
 
826
- # Returns current <tt>ActionController::Parameters</tt> instance with
830
+ # Returns the current <tt>ActionController::Parameters</tt> instance with
827
831
  # +other_hash+ merged into current hash.
828
832
  def merge!(other_hash)
829
833
  @parameters.merge!(other_hash.to_h)
830
834
  self
831
835
  end
832
836
 
833
- # Returns a new <tt>ActionController::Parameters</tt> with all keys from
834
- # current hash merged into +other_hash+.
837
+ # Returns a new <tt>ActionController::Parameters</tt> instance with all keys
838
+ # from current hash merged into +other_hash+.
835
839
  def reverse_merge(other_hash)
836
840
  new_instance_with_inherited_permitted_status(
837
841
  other_hash.to_h.merge(@parameters)
@@ -839,7 +843,7 @@ module ActionController
839
843
  end
840
844
  alias_method :with_defaults, :reverse_merge
841
845
 
842
- # Returns current <tt>ActionController::Parameters</tt> instance with
846
+ # Returns the current <tt>ActionController::Parameters</tt> instance with
843
847
  # current hash merged into +other_hash+.
844
848
  def reverse_merge!(other_hash)
845
849
  @parameters.merge!(other_hash.to_h) { |key, left, right| left }
@@ -885,9 +889,13 @@ module ActionController
885
889
  end
886
890
  end
887
891
 
888
- # Returns duplicate of object including all parameters.
892
+ def encode_with(coder) # :nodoc:
893
+ coder.map = { "parameters" => @parameters, "permitted" => @permitted }
894
+ end
895
+
896
+ # Returns a duplicate +ActionController::Parameters+ instance with the same permitted parameters.
889
897
  def deep_dup
890
- self.class.new(@parameters.deep_dup).tap do |duplicate|
898
+ self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate|
891
899
  duplicate.permitted = @permitted
892
900
  end
893
901
  end
@@ -909,7 +917,7 @@ module ActionController
909
917
 
910
918
  private
911
919
  def new_instance_with_inherited_permitted_status(hash)
912
- self.class.new(hash).tap do |new_instance|
920
+ self.class.new(hash, @logging_context).tap do |new_instance|
913
921
  new_instance.permitted = @permitted
914
922
  end
915
923
  end
@@ -943,18 +951,24 @@ module ActionController
943
951
  converted_arrays << converted.dup
944
952
  converted
945
953
  when Hash
946
- self.class.new(value)
954
+ self.class.new(value, @logging_context)
947
955
  else
948
956
  value
949
957
  end
950
958
  end
951
959
 
952
- def each_element(object, &block)
960
+ def specify_numeric_keys?(filter)
961
+ if filter.respond_to?(:keys)
962
+ filter.keys.any? { |key| /\A-?\d+\z/.match?(key) }
963
+ end
964
+ end
965
+
966
+ def each_element(object, filter, &block)
953
967
  case object
954
968
  when Array
955
- object.grep(Parameters).map { |el| yield el }.compact
969
+ object.grep(Parameters).filter_map(&block)
956
970
  when Parameters
957
- if object.nested_attributes?
971
+ if object.nested_attributes? && !specify_numeric_keys?(filter)
958
972
  object.each_nested_attribute(&block)
959
973
  else
960
974
  yield object
@@ -968,7 +982,7 @@ module ActionController
968
982
  case self.class.action_on_unpermitted_parameters
969
983
  when :log
970
984
  name = "unpermitted_parameters.action_controller"
971
- ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys)
985
+ ActiveSupport::Notifications.instrument(name, keys: unpermitted_keys, context: @logging_context)
972
986
  when :raise
973
987
  raise ActionController::UnpermittedParameters.new(unpermitted_keys)
974
988
  end
@@ -986,10 +1000,11 @@ module ActionController
986
1000
  # This is a list of permitted scalar types that includes the ones
987
1001
  # supported in XML and JSON requests.
988
1002
  #
989
- # This list is in particular used to filter ordinary requests, String goes
1003
+ # This list is in particular used to filter ordinary requests, \String goes
990
1004
  # as first element to quickly short-circuit the common case.
991
1005
  #
992
- # If you modify this collection please update the API of +permit+ above.
1006
+ # If you modify this collection please update the one in the #permit doc
1007
+ # as well.
993
1008
  PERMITTED_SCALAR_TYPES = [
994
1009
  String,
995
1010
  Symbol,
@@ -1045,8 +1060,8 @@ module ActionController
1045
1060
  value.is_a?(Array) || value.is_a?(Parameters)
1046
1061
  end
1047
1062
 
1048
- EMPTY_ARRAY = []
1049
- EMPTY_HASH = {}
1063
+ EMPTY_ARRAY = [] # :nodoc:
1064
+ EMPTY_HASH = {} # :nodoc:
1050
1065
  def hash_filter(params, filter)
1051
1066
  filter = filter.with_indifferent_access
1052
1067
 
@@ -1067,7 +1082,7 @@ module ActionController
1067
1082
  end
1068
1083
  elsif non_scalar?(value)
1069
1084
  # Declaration { user: :name } or { user: [:name, :age, { address: ... }] }.
1070
- params[key] = each_element(value) do |element|
1085
+ params[key] = each_element(value, filter[key]) do |element|
1071
1086
  element.permit(*Array.wrap(filter[key]))
1072
1087
  end
1073
1088
  end
@@ -1184,7 +1199,15 @@ module ActionController
1184
1199
  # Returns a new ActionController::Parameters object that
1185
1200
  # has been instantiated with the <tt>request.parameters</tt>.
1186
1201
  def params
1187
- @_params ||= Parameters.new(request.parameters)
1202
+ @_params ||= begin
1203
+ context = {
1204
+ controller: self.class.name,
1205
+ action: action_name,
1206
+ request: request,
1207
+ params: request.filtered_parameters
1208
+ }
1209
+ Parameters.new(request.parameters, context)
1210
+ end
1188
1211
  end
1189
1212
 
1190
1213
  # Assigns the given +value+ to the +params+ hash. If +value+
@@ -2,10 +2,17 @@
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:
7
+ def clear_instance_variables_between_requests
8
+ if defined?(@_ivars)
9
+ new_ivars = instance_variables - @_ivars
10
+ new_ivars.each { |ivar| remove_instance_variable(ivar) }
11
+ end
12
+
13
+ @_ivars = instance_variables
14
+ end
15
+
9
16
  def recycle!
10
17
  @_url_options = nil
11
18
  self.formats = nil
@@ -4,12 +4,10 @@ module ActionController
4
4
  # Includes +url_for+ into the host class. The class has to provide a +RouteSet+ by implementing
5
5
  # the <tt>_routes</tt> method. Otherwise, an exception will be raised.
6
6
  #
7
- # In addition to <tt>AbstractController::UrlFor</tt>, this module accesses the HTTP layer to define
7
+ # In addition to AbstractController::UrlFor, this module accesses the HTTP layer to define
8
8
  # URL options like the +host+. In order to do so, this module requires the host class
9
- # to implement +env+ which needs to be Rack-compatible and +request+
10
- # which is either an instance of +ActionDispatch::Request+ or an object
11
- # that responds to the +host+, +optional_port+, +protocol+ and
12
- # +symbolized_path_parameter+ methods.
9
+ # to implement +env+ which needs to be Rack-compatible, and +request+ which
10
+ # returns an ActionDispatch::Request instance.
13
11
  #
14
12
  # class RootUrl
15
13
  # include ActionController::UrlFor