actionpack 3.2.22.5 → 4.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +641 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller.rb +1 -8
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +23 -11
- data/lib/abstract_controller/layouts.rb +68 -73
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +22 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/action_controller.rb +15 -6
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/log_subscriber.rb +11 -8
- data/lib/action_controller/metal.rb +16 -30
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +32 -9
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +6 -9
- data/lib/action_controller/metal/hide_actions.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +105 -87
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +141 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +8 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +516 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +27 -25
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +215 -123
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +27 -19
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
- data/lib/action_dispatch/http/mime_type.rb +145 -113
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +12 -5
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +49 -18
- data/lib/action_dispatch/http/response.rb +129 -35
- data/lib/action_dispatch/http/upload.rb +60 -17
- data/lib/action_dispatch/http/url.rb +53 -31
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +116 -0
- data/lib/action_dispatch/journey/router.rb +164 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +189 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +168 -57
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +5 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing.rb +41 -40
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +501 -273
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +203 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
- data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +41 -22
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +17 -8
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +91 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
- data/lib/action_view/helpers/asset_url_helper.rb +354 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +42 -29
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +268 -247
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +904 -547
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +188 -88
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -354
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -4
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +43 -37
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/tags/base.rb +148 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +41 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/text_helper.rb +126 -113
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +200 -271
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -39
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +9 -39
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +10 -19
- data/lib/action_view/renderer/partial_renderer.rb +144 -81
- data/lib/action_view/renderer/renderer.rb +2 -19
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +14 -13
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template.rb +22 -21
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +11 -16
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/resolver.rb +111 -83
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/test_case.rb +66 -43
- data/lib/action_view/testing/resolvers.rb +3 -2
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- metadata +135 -125
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,9 +1,8 @@
|
|
1
|
-
require 'active_support/core_ext/class/attribute'
|
2
1
|
require 'active_support/core_ext/hash/slice'
|
3
2
|
require 'active_support/core_ext/hash/except'
|
4
|
-
require 'active_support/core_ext/array/wrap'
|
5
3
|
require 'active_support/core_ext/module/anonymous'
|
6
|
-
require '
|
4
|
+
require 'active_support/core_ext/struct'
|
5
|
+
require 'action_dispatch/http/mime_type'
|
7
6
|
|
8
7
|
module ActionController
|
9
8
|
# Wraps the parameters hash into a nested hash. This will allow clients to submit
|
@@ -17,7 +16,7 @@ module ActionController
|
|
17
16
|
# a non-empty array:
|
18
17
|
#
|
19
18
|
# class UsersController < ApplicationController
|
20
|
-
# wrap_parameters :
|
19
|
+
# wrap_parameters format: [:json, :xml]
|
21
20
|
# end
|
22
21
|
#
|
23
22
|
# If you enable +ParamsWrapper+ for +:json+ format, instead of having to
|
@@ -40,16 +39,15 @@ module ActionController
|
|
40
39
|
# +:exclude+ options like this:
|
41
40
|
#
|
42
41
|
# class UsersController < ApplicationController
|
43
|
-
# wrap_parameters :person, :
|
42
|
+
# wrap_parameters :person, include: [:username, :password]
|
44
43
|
# end
|
45
44
|
#
|
46
|
-
# On ActiveRecord models with no +:include+ or +:exclude+ option set,
|
47
|
-
#
|
48
|
-
#
|
49
|
-
# method attribute_names.
|
45
|
+
# On ActiveRecord models with no +:include+ or +:exclude+ option set,
|
46
|
+
# it will only wrap the parameters returned by the class method
|
47
|
+
# <tt>attribute_names</tt>.
|
50
48
|
#
|
51
49
|
# If you're going to pass the parameters to an +ActiveModel+ object (such as
|
52
|
-
#
|
50
|
+
# <tt>User.new(params[:user])</tt>), you might consider passing the model class to
|
53
51
|
# the method instead. The +ParamsWrapper+ will actually try to determine the
|
54
52
|
# list of attribute names from the model and only wrap those attributes:
|
55
53
|
#
|
@@ -67,7 +65,7 @@ module ActionController
|
|
67
65
|
# class Admin::UsersController < ApplicationController
|
68
66
|
# end
|
69
67
|
#
|
70
|
-
# will try to check if
|
68
|
+
# will try to check if <tt>Admin::User</tt> or +User+ model exists, and use it to
|
71
69
|
# determine the wrapper key respectively. If both models don't exist,
|
72
70
|
# it will then fallback to use +user+ as the key.
|
73
71
|
module ParamsWrapper
|
@@ -75,17 +73,104 @@ module ActionController
|
|
75
73
|
|
76
74
|
EXCLUDE_PARAMETERS = %w(authenticity_token _method utf8)
|
77
75
|
|
76
|
+
require 'mutex_m'
|
77
|
+
|
78
|
+
class Options < Struct.new(:name, :format, :include, :exclude, :klass, :model) # :nodoc:
|
79
|
+
include Mutex_m
|
80
|
+
|
81
|
+
def self.from_hash(hash)
|
82
|
+
name = hash[:name]
|
83
|
+
format = Array(hash[:format])
|
84
|
+
include = hash[:include] && Array(hash[:include]).collect(&:to_s)
|
85
|
+
exclude = hash[:exclude] && Array(hash[:exclude]).collect(&:to_s)
|
86
|
+
new name, format, include, exclude, nil, nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def initialize(name, format, include, exclude, klass, model) # nodoc
|
90
|
+
super
|
91
|
+
@include_set = include
|
92
|
+
@name_set = name
|
93
|
+
end
|
94
|
+
|
95
|
+
def model
|
96
|
+
super || synchronize { super || self.model = _default_wrap_model }
|
97
|
+
end
|
98
|
+
|
99
|
+
def include
|
100
|
+
return super if @include_set
|
101
|
+
|
102
|
+
m = model
|
103
|
+
synchronize do
|
104
|
+
return super if @include_set
|
105
|
+
|
106
|
+
@include_set = true
|
107
|
+
|
108
|
+
unless super || exclude
|
109
|
+
if m.respond_to?(:attribute_names) && m.attribute_names.any?
|
110
|
+
self.include = m.attribute_names
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def name
|
117
|
+
return super if @name_set
|
118
|
+
|
119
|
+
m = model
|
120
|
+
synchronize do
|
121
|
+
return super if @name_set
|
122
|
+
|
123
|
+
@name_set = true
|
124
|
+
|
125
|
+
unless super || klass.anonymous?
|
126
|
+
self.name = m ? m.to_s.demodulize.underscore :
|
127
|
+
klass.controller_name.singularize
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
# Determine the wrapper model from the controller's name. By convention,
|
134
|
+
# this could be done by trying to find the defined model that has the
|
135
|
+
# same singularize name as the controller. For example, +UsersController+
|
136
|
+
# will try to find if the +User+ model exists.
|
137
|
+
#
|
138
|
+
# This method also does namespace lookup. Foo::Bar::UsersController will
|
139
|
+
# try to find Foo::Bar::User, Foo::User and finally User.
|
140
|
+
def _default_wrap_model #:nodoc:
|
141
|
+
return nil if klass.anonymous?
|
142
|
+
model_name = klass.name.sub(/Controller$/, '').classify
|
143
|
+
|
144
|
+
begin
|
145
|
+
if model_klass = model_name.safe_constantize
|
146
|
+
model_klass
|
147
|
+
else
|
148
|
+
namespaces = model_name.split("::")
|
149
|
+
namespaces.delete_at(-2)
|
150
|
+
break if namespaces.last == model_name
|
151
|
+
model_name = namespaces.join("::")
|
152
|
+
end
|
153
|
+
end until model_klass
|
154
|
+
|
155
|
+
model_klass
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
78
159
|
included do
|
79
160
|
class_attribute :_wrapper_options
|
80
|
-
self._wrapper_options =
|
161
|
+
self._wrapper_options = Options.from_hash(format: [])
|
81
162
|
end
|
82
163
|
|
83
164
|
module ClassMethods
|
165
|
+
def _set_wrapper_options(options)
|
166
|
+
self._wrapper_options = Options.from_hash(options)
|
167
|
+
end
|
168
|
+
|
84
169
|
# Sets the name of the wrapper key, or the model which +ParamsWrapper+
|
85
170
|
# would use to determine the attribute names from.
|
86
171
|
#
|
87
172
|
# ==== Examples
|
88
|
-
# wrap_parameters :
|
173
|
+
# wrap_parameters format: :xml
|
89
174
|
# # enables the parameter wrapper for XML format
|
90
175
|
#
|
91
176
|
# wrap_parameters :person
|
@@ -95,7 +180,7 @@ module ActionController
|
|
95
180
|
# # wraps parameters by determining the wrapper key from Person class
|
96
181
|
# (+person+, in this case) and the list of attribute names
|
97
182
|
#
|
98
|
-
# wrap_parameters :
|
183
|
+
# wrap_parameters include: [:username, :title]
|
99
184
|
# # wraps only +:username+ and +:title+ attributes from parameters.
|
100
185
|
#
|
101
186
|
# wrap_parameters false
|
@@ -122,71 +207,24 @@ module ActionController
|
|
122
207
|
model = name_or_model_or_options
|
123
208
|
end
|
124
209
|
|
125
|
-
|
210
|
+
opts = Options.from_hash _wrapper_options.to_h.slice(:format).merge(options)
|
211
|
+
opts.model = model
|
212
|
+
opts.klass = self
|
213
|
+
|
214
|
+
self._wrapper_options = opts
|
126
215
|
end
|
127
216
|
|
128
217
|
# Sets the default wrapper key or model which will be used to determine
|
129
218
|
# wrapper key and attribute names. Will be called automatically when the
|
130
219
|
# module is inherited.
|
131
220
|
def inherited(klass)
|
132
|
-
if klass._wrapper_options
|
133
|
-
klass.
|
221
|
+
if klass._wrapper_options.format.any?
|
222
|
+
params = klass._wrapper_options.dup
|
223
|
+
params.klass = klass
|
224
|
+
klass._wrapper_options = params
|
134
225
|
end
|
135
226
|
super
|
136
227
|
end
|
137
|
-
|
138
|
-
protected
|
139
|
-
|
140
|
-
# Determine the wrapper model from the controller's name. By convention,
|
141
|
-
# this could be done by trying to find the defined model that has the
|
142
|
-
# same singularize name as the controller. For example, +UsersController+
|
143
|
-
# will try to find if the +User+ model exists.
|
144
|
-
#
|
145
|
-
# This method also does namespace lookup. Foo::Bar::UsersController will
|
146
|
-
# try to find Foo::Bar::User, Foo::User and finally User.
|
147
|
-
def _default_wrap_model #:nodoc:
|
148
|
-
return nil if self.anonymous?
|
149
|
-
model_name = self.name.sub(/Controller$/, '').classify
|
150
|
-
|
151
|
-
begin
|
152
|
-
if model_klass = model_name.safe_constantize
|
153
|
-
model_klass
|
154
|
-
else
|
155
|
-
namespaces = model_name.split("::")
|
156
|
-
namespaces.delete_at(-2)
|
157
|
-
break if namespaces.last == model_name
|
158
|
-
model_name = namespaces.join("::")
|
159
|
-
end
|
160
|
-
end until model_klass
|
161
|
-
|
162
|
-
model_klass
|
163
|
-
end
|
164
|
-
|
165
|
-
def _set_wrapper_defaults(options, model=nil)
|
166
|
-
options = options.dup
|
167
|
-
|
168
|
-
unless options[:include] || options[:exclude]
|
169
|
-
model ||= _default_wrap_model
|
170
|
-
role = options.has_key?(:as) ? options[:as] : :default
|
171
|
-
if model.respond_to?(:accessible_attributes) && model.accessible_attributes(role).present?
|
172
|
-
options[:include] = model.accessible_attributes(role).to_a
|
173
|
-
elsif model.respond_to?(:attribute_names) && model.attribute_names.present?
|
174
|
-
options[:include] = model.attribute_names
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
unless options[:name] || self.anonymous?
|
179
|
-
model ||= _default_wrap_model
|
180
|
-
options[:name] = model ? model.to_s.demodulize.underscore :
|
181
|
-
controller_name.singularize
|
182
|
-
end
|
183
|
-
|
184
|
-
options[:include] = Array.wrap(options[:include]).collect(&:to_s) if options[:include]
|
185
|
-
options[:exclude] = Array.wrap(options[:exclude]).collect(&:to_s) if options[:exclude]
|
186
|
-
options[:format] = Array.wrap(options[:format])
|
187
|
-
|
188
|
-
self._wrapper_options = options
|
189
|
-
end
|
190
228
|
end
|
191
229
|
|
192
230
|
# Performs parameters wrapping upon the request. Will be called automatically
|
@@ -211,20 +249,20 @@ module ActionController
|
|
211
249
|
|
212
250
|
# Returns the wrapper key which will use to stored wrapped parameters.
|
213
251
|
def _wrapper_key
|
214
|
-
_wrapper_options
|
252
|
+
_wrapper_options.name
|
215
253
|
end
|
216
254
|
|
217
255
|
# Returns the list of enabled formats.
|
218
256
|
def _wrapper_formats
|
219
|
-
_wrapper_options
|
257
|
+
_wrapper_options.format
|
220
258
|
end
|
221
259
|
|
222
260
|
# Returns the list of parameters which will be selected for wrapped.
|
223
261
|
def _wrap_parameters(parameters)
|
224
|
-
value = if include_only = _wrapper_options
|
262
|
+
value = if include_only = _wrapper_options.include
|
225
263
|
parameters.slice(*include_only)
|
226
264
|
else
|
227
|
-
exclude = _wrapper_options
|
265
|
+
exclude = _wrapper_options.exclude || []
|
228
266
|
parameters.except(*(exclude + EXCLUDE_PARAMETERS))
|
229
267
|
end
|
230
268
|
|
@@ -8,9 +8,8 @@ module ActionController
|
|
8
8
|
delegate :headers, :status=, :location=, :content_type=,
|
9
9
|
:status, :location, :content_type, :to => "@_response"
|
10
10
|
|
11
|
-
def dispatch(action, request
|
12
|
-
|
13
|
-
@_response.request ||= request
|
11
|
+
def dispatch(action, request)
|
12
|
+
set_response!(request)
|
14
13
|
super(action, request)
|
15
14
|
end
|
16
15
|
|
@@ -22,5 +21,12 @@ module ActionController
|
|
22
21
|
def reset_session
|
23
22
|
@_request.reset_session
|
24
23
|
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def set_response!(request)
|
28
|
+
@_response = ActionDispatch::Response.new
|
29
|
+
@_response.request = request
|
30
|
+
end
|
25
31
|
end
|
26
32
|
end
|
@@ -24,8 +24,7 @@ module ActionController
|
|
24
24
|
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
|
25
25
|
# Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
|
26
26
|
#
|
27
|
-
#
|
28
|
-
# redirect_to :action => "show", :id => 5
|
27
|
+
# redirect_to action: "show", id: 5
|
29
28
|
# redirect_to post
|
30
29
|
# redirect_to "http://www.rubyonrails.org"
|
31
30
|
# redirect_to "/images/screenshot.jpg"
|
@@ -33,13 +32,12 @@ module ActionController
|
|
33
32
|
# redirect_to :back
|
34
33
|
# redirect_to proc { edit_post_url(@post) }
|
35
34
|
#
|
36
|
-
# The redirection happens as a "302
|
35
|
+
# The redirection happens as a "302 Found" header unless otherwise specified.
|
37
36
|
#
|
38
|
-
#
|
39
|
-
# redirect_to
|
40
|
-
# redirect_to
|
41
|
-
# redirect_to
|
42
|
-
# redirect_to :action=>'atom', :status => 302
|
37
|
+
# redirect_to post_url(@post), status: :found
|
38
|
+
# redirect_to action: 'atom', status: :moved_permanently
|
39
|
+
# redirect_to post_url(@post), status: 301
|
40
|
+
# redirect_to action: 'atom', status: 302
|
43
41
|
#
|
44
42
|
# The status code can either be a standard {HTTP Status code}[http://www.iana.org/assignments/http-status-codes] as an
|
45
43
|
# integer, or a symbol representing the downcased, underscored and symbolized description.
|
@@ -51,18 +49,16 @@ module ActionController
|
|
51
49
|
# around this you can return a <tt>303 See Other</tt> status code which will be
|
52
50
|
# followed using a GET request.
|
53
51
|
#
|
54
|
-
#
|
55
|
-
# redirect_to
|
56
|
-
# redirect_to :action => 'index', :status => 303
|
52
|
+
# redirect_to posts_url, status: :see_other
|
53
|
+
# redirect_to action: 'index', status: 303
|
57
54
|
#
|
58
55
|
# It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names
|
59
56
|
# +alert+ and +notice+ as well as a general purpose +flash+ bucket.
|
60
57
|
#
|
61
|
-
#
|
62
|
-
# redirect_to post_url(@post), :
|
63
|
-
# redirect_to post_url(@post), :
|
64
|
-
# redirect_to
|
65
|
-
# redirect_to { :action=>'atom' }, :alert => "Something serious happened"
|
58
|
+
# redirect_to post_url(@post), alert: "Watch it, mister!"
|
59
|
+
# redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
|
60
|
+
# redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
|
61
|
+
# redirect_to { action: 'atom' }, alert: "Something serious happened"
|
66
62
|
#
|
67
63
|
# When using <tt>redirect_to :back</tt>, if there is no referrer, ActionController::RedirectBackError will be raised. You may specify some fallback
|
68
64
|
# behavior for this case by rescuing ActionController::RedirectBackError.
|
@@ -92,18 +88,17 @@ module ActionController
|
|
92
88
|
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
93
89
|
# characters; and is terminated by a colon (":").
|
94
90
|
# The protocol relative scheme starts with a double slash "//"
|
95
|
-
when %r{
|
91
|
+
when %r{\A(\w[\w+.-]*:|//).*}
|
96
92
|
options
|
97
93
|
when String
|
98
94
|
request.protocol + request.host_with_port + options
|
99
95
|
when :back
|
100
|
-
|
101
|
-
refer
|
96
|
+
request.headers["Referer"] or raise RedirectBackError
|
102
97
|
when Proc
|
103
98
|
_compute_redirect_to_location options.call
|
104
99
|
else
|
105
100
|
url_for(options)
|
106
|
-
end.
|
101
|
+
end.delete("\0\r\n")
|
107
102
|
end
|
108
103
|
end
|
109
104
|
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/class/attribute'
|
2
|
-
require 'active_support/core_ext/object/blank'
|
3
1
|
require 'set'
|
4
2
|
|
5
3
|
module ActionController
|
@@ -49,14 +47,13 @@ module ActionController
|
|
49
47
|
# is the value paired with its key and the second is the remaining
|
50
48
|
# hash of options passed to +render+.
|
51
49
|
#
|
52
|
-
# === Example
|
53
50
|
# Create a csv renderer:
|
54
51
|
#
|
55
52
|
# ActionController::Renderers.add :csv do |obj, options|
|
56
53
|
# filename = options[:filename] || 'data'
|
57
54
|
# str = obj.respond_to?(:to_csv) ? obj.to_csv : obj.to_s
|
58
|
-
# send_data str, :
|
59
|
-
# :
|
55
|
+
# send_data str, type: Mime::CSV,
|
56
|
+
# disposition: "attachment; filename=#{filename}.csv"
|
60
57
|
# end
|
61
58
|
#
|
62
59
|
# Note that we used Mime::CSV for the csv mime type as it comes with Rails.
|
@@ -69,7 +66,7 @@ module ActionController
|
|
69
66
|
# @csvable = Csvable.find(params[:id])
|
70
67
|
# respond_to do |format|
|
71
68
|
# format.html
|
72
|
-
# format.csv { render :
|
69
|
+
# format.csv { render csv: @csvable, filename: @csvable.name }
|
73
70
|
# }
|
74
71
|
# end
|
75
72
|
# To use renderers and their mime types in more concise ways, see
|
@@ -91,9 +88,14 @@ module ActionController
|
|
91
88
|
|
92
89
|
add :json do |json, options|
|
93
90
|
json = json.to_json(options) unless json.kind_of?(String)
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
|
92
|
+
if options[:callback].present?
|
93
|
+
self.content_type ||= Mime::JS
|
94
|
+
"#{options[:callback]}(#{json})"
|
95
|
+
else
|
96
|
+
self.content_type ||= Mime::JSON
|
97
|
+
json
|
98
|
+
end
|
97
99
|
end
|
98
100
|
|
99
101
|
add :js do |js, options|
|
@@ -29,6 +29,10 @@ module ActionController
|
|
29
29
|
self.response_body = nil
|
30
30
|
end
|
31
31
|
|
32
|
+
def render_to_body(*)
|
33
|
+
super || " "
|
34
|
+
end
|
35
|
+
|
32
36
|
private
|
33
37
|
|
34
38
|
# Normalize arguments by catching blocks and setting them on :update.
|
@@ -44,6 +48,10 @@ module ActionController
|
|
44
48
|
options[:text] = options[:text].to_text
|
45
49
|
end
|
46
50
|
|
51
|
+
if options.delete(:nothing) || (options.key?(:text) && options[:text].nil?)
|
52
|
+
options[:text] = " "
|
53
|
+
end
|
54
|
+
|
47
55
|
if options[:status]
|
48
56
|
options[:status] = Rack::Utils.status_code(options[:status])
|
49
57
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'rack/session/abstract/id'
|
2
2
|
require 'action_controller/metal/exceptions'
|
3
3
|
|
4
4
|
module ActionController #:nodoc:
|
@@ -14,10 +14,23 @@ module ActionController #:nodoc:
|
|
14
14
|
# authentication scheme there anyway). Also, GET requests are not protected as these
|
15
15
|
# should be idempotent.
|
16
16
|
#
|
17
|
+
# It's important to remember that XML or JSON requests are also affected and if
|
18
|
+
# you're building an API you'll need something like:
|
19
|
+
#
|
20
|
+
# class ApplicationController < ActionController::Base
|
21
|
+
# protect_from_forgery
|
22
|
+
# skip_before_action :verify_authenticity_token, if: :json_request?
|
23
|
+
#
|
24
|
+
# protected
|
25
|
+
#
|
26
|
+
# def json_request?
|
27
|
+
# request.format.json?
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
17
31
|
# CSRF protection is turned on with the <tt>protect_from_forgery</tt> method,
|
18
32
|
# which checks the token and resets the session if it doesn't match what was expected.
|
19
33
|
# A call to this method is generated for new \Rails applications by default.
|
20
|
-
# You can customize the error message by editing public/422.html.
|
21
34
|
#
|
22
35
|
# The token parameter is named <tt>authenticity_token</tt> by default. The name and
|
23
36
|
# value of this token must be added to every layout that renders forms by including
|
@@ -37,6 +50,10 @@ module ActionController #:nodoc:
|
|
37
50
|
config_accessor :request_forgery_protection_token
|
38
51
|
self.request_forgery_protection_token ||= :authenticity_token
|
39
52
|
|
53
|
+
# Holds the class which implements the request forgery protection.
|
54
|
+
config_accessor :forgery_protection_strategy
|
55
|
+
self.forgery_protection_strategy = nil
|
56
|
+
|
40
57
|
# Controls whether request forgery protection is turned on or not. Turned off by default only in test mode.
|
41
58
|
config_accessor :allow_forgery_protection
|
42
59
|
self.allow_forgery_protection = true if allow_forgery_protection.nil?
|
@@ -48,50 +65,126 @@ module ActionController #:nodoc:
|
|
48
65
|
module ClassMethods
|
49
66
|
# Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
|
50
67
|
#
|
51
|
-
# Example:
|
52
|
-
#
|
53
68
|
# class FooController < ApplicationController
|
54
|
-
# protect_from_forgery :
|
69
|
+
# protect_from_forgery except: :index
|
55
70
|
#
|
56
71
|
# You can disable csrf protection on controller-by-controller basis:
|
57
72
|
#
|
58
|
-
#
|
73
|
+
# skip_before_action :verify_authenticity_token
|
59
74
|
#
|
60
75
|
# It can also be disabled for specific controller actions:
|
61
76
|
#
|
62
|
-
#
|
77
|
+
# skip_before_action :verify_authenticity_token, except: [:create]
|
63
78
|
#
|
64
79
|
# Valid Options:
|
65
80
|
#
|
66
|
-
# * <tt>:only/:except</tt> - Passed to the <tt>
|
81
|
+
# * <tt>:only/:except</tt> - Passed to the <tt>before_action</tt> call. Set which actions are verified.
|
82
|
+
# * <tt>:with</tt> - Set the method to handle unverified request.
|
83
|
+
#
|
84
|
+
# Valid unverified request handling methods are:
|
85
|
+
# * <tt>:exception</tt> - Raises ActionController::InvalidAuthenticityToken exception.
|
86
|
+
# * <tt>:reset_session</tt> - Resets the session.
|
87
|
+
# * <tt>:null_session</tt> - Provides an empty session during request but doesn't reset it completely. Used as default if <tt>:with</tt> option is not specified.
|
67
88
|
def protect_from_forgery(options = {})
|
89
|
+
self.forgery_protection_strategy = protection_method_class(options[:with] || :null_session)
|
68
90
|
self.request_forgery_protection_token ||= :authenticity_token
|
69
|
-
|
91
|
+
prepend_before_action :verify_authenticity_token, options
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def protection_method_class(name)
|
97
|
+
ActionController::RequestForgeryProtection::ProtectionMethods.const_get(name.to_s.classify)
|
98
|
+
rescue NameError
|
99
|
+
raise ArgumentError, 'Invalid request forgery protection method, use :null_session, :exception, or :reset_session'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
module ProtectionMethods
|
104
|
+
class NullSession
|
105
|
+
def initialize(controller)
|
106
|
+
@controller = controller
|
107
|
+
end
|
108
|
+
|
109
|
+
# This is the method that defines the application behavior when a request is found to be unverified.
|
110
|
+
def handle_unverified_request
|
111
|
+
request = @controller.request
|
112
|
+
request.session = NullSessionHash.new(request.env)
|
113
|
+
request.env['action_dispatch.request.flash_hash'] = nil
|
114
|
+
request.env['rack.session.options'] = { skip: true }
|
115
|
+
request.env['action_dispatch.cookies'] = NullCookieJar.build(request)
|
116
|
+
end
|
117
|
+
|
118
|
+
protected
|
119
|
+
|
120
|
+
class NullSessionHash < Rack::Session::Abstract::SessionHash #:nodoc:
|
121
|
+
def initialize(env)
|
122
|
+
super(nil, env)
|
123
|
+
@data = {}
|
124
|
+
@loaded = true
|
125
|
+
end
|
126
|
+
|
127
|
+
def exists?
|
128
|
+
true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class NullCookieJar < ActionDispatch::Cookies::CookieJar #:nodoc:
|
133
|
+
def self.build(request)
|
134
|
+
key_generator = request.env[ActionDispatch::Cookies::GENERATOR_KEY]
|
135
|
+
host = request.host
|
136
|
+
secure = request.ssl?
|
137
|
+
|
138
|
+
new(key_generator, host, secure, options_for_env({}))
|
139
|
+
end
|
140
|
+
|
141
|
+
def write(*)
|
142
|
+
# nothing
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
class ResetSession
|
148
|
+
def initialize(controller)
|
149
|
+
@controller = controller
|
150
|
+
end
|
151
|
+
|
152
|
+
def handle_unverified_request
|
153
|
+
@controller.reset_session
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
class Exception
|
158
|
+
def initialize(controller)
|
159
|
+
@controller = controller
|
160
|
+
end
|
161
|
+
|
162
|
+
def handle_unverified_request
|
163
|
+
raise ActionController::InvalidAuthenticityToken
|
164
|
+
end
|
70
165
|
end
|
71
166
|
end
|
72
167
|
|
73
168
|
protected
|
74
|
-
|
169
|
+
def handle_unverified_request
|
170
|
+
forgery_protection_strategy.new(self).handle_unverified_request
|
171
|
+
end
|
172
|
+
|
173
|
+
# The actual before_action that is used. Modify this to change how you handle unverified requests.
|
75
174
|
def verify_authenticity_token
|
76
175
|
unless verified_request?
|
77
|
-
logger.warn "
|
176
|
+
logger.warn "Can't verify CSRF token authenticity" if logger
|
78
177
|
handle_unverified_request
|
79
178
|
end
|
80
179
|
end
|
81
180
|
|
82
|
-
# This is the method that defines the application behavior when a request is found to be unverified.
|
83
|
-
# By default, \Rails resets the session when it finds an unverified request.
|
84
|
-
def handle_unverified_request
|
85
|
-
reset_session
|
86
|
-
end
|
87
|
-
|
88
181
|
# Returns true or false if a request is verified. Checks:
|
89
182
|
#
|
90
|
-
# * is it a GET request? Gets should be safe and idempotent
|
183
|
+
# * is it a GET or HEAD request? Gets should be safe and idempotent
|
91
184
|
# * Does the form_authenticity_token match the given token value from the params?
|
92
185
|
# * Does the X-CSRF-Token header match the form_authenticity_token
|
93
186
|
def verified_request?
|
94
|
-
!protect_against_forgery? || request.get? ||
|
187
|
+
!protect_against_forgery? || request.get? || request.head? ||
|
95
188
|
form_authenticity_token == params[request_forgery_protection_token] ||
|
96
189
|
form_authenticity_token == request.headers['X-CSRF-Token']
|
97
190
|
end
|