actionpack 3.0.0.beta → 3.0.0.beta2
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.
- data/CHANGELOG +291 -260
- data/lib/abstract_controller.rb +5 -2
- data/lib/abstract_controller/assigns.rb +21 -0
- data/lib/abstract_controller/base.rb +13 -5
- data/lib/abstract_controller/collector.rb +2 -0
- data/lib/abstract_controller/helpers.rb +4 -14
- data/lib/abstract_controller/layouts.rb +50 -99
- data/lib/abstract_controller/logger.rb +2 -2
- data/lib/abstract_controller/rendering.rb +105 -173
- data/lib/abstract_controller/view_paths.rb +69 -0
- data/lib/action_controller.rb +1 -2
- data/lib/action_controller/base.rb +10 -32
- data/lib/action_controller/caching.rb +19 -18
- data/lib/action_controller/caching/actions.rb +17 -11
- data/lib/action_controller/caching/fragments.rb +5 -17
- data/lib/action_controller/caching/pages.rb +24 -24
- data/lib/action_controller/caching/sweeping.rb +1 -3
- data/lib/action_controller/deprecated.rb +0 -2
- data/lib/action_controller/deprecated/base.rb +143 -0
- data/lib/action_controller/metal.rb +29 -26
- data/lib/action_controller/metal/compatibility.rb +18 -87
- data/lib/action_controller/metal/cookies.rb +0 -1
- data/lib/action_controller/metal/head.rb +1 -0
- data/lib/action_controller/metal/helpers.rb +2 -2
- data/lib/action_controller/metal/hide_actions.rb +4 -6
- data/lib/action_controller/metal/http_authentication.rb +18 -33
- data/lib/action_controller/metal/implicit_render.rb +21 -0
- data/lib/action_controller/metal/instrumentation.rb +1 -1
- data/lib/action_controller/metal/mime_responds.rb +2 -1
- data/lib/action_controller/metal/rack_delegation.rb +3 -8
- data/lib/action_controller/metal/redirecting.rb +2 -1
- data/lib/action_controller/metal/renderers.rb +4 -2
- data/lib/action_controller/metal/rendering.rb +31 -44
- data/lib/action_controller/metal/request_forgery_protection.rb +41 -4
- data/lib/action_controller/metal/responder.rb +2 -0
- data/lib/action_controller/metal/session_management.rb +0 -36
- data/lib/action_controller/metal/streaming.rb +20 -47
- data/lib/action_controller/metal/testing.rb +0 -1
- data/lib/action_controller/metal/url_for.rb +11 -148
- data/lib/action_controller/middleware.rb +2 -1
- data/lib/action_controller/polymorphic_routes.rb +1 -2
- data/lib/action_controller/railtie.rb +63 -10
- data/lib/action_controller/railties/{subscriber.rb → log_subscriber.rb} +5 -12
- data/lib/action_controller/railties/url_helpers.rb +14 -0
- data/lib/action_controller/record_identifier.rb +20 -1
- data/lib/action_controller/test_case.rb +123 -12
- data/lib/action_dispatch.rb +1 -0
- data/lib/action_dispatch/http/cache.rb +20 -3
- data/lib/action_dispatch/http/filter_parameters.rb +40 -25
- data/lib/action_dispatch/http/mime_negotiation.rb +6 -17
- data/lib/action_dispatch/http/mime_type.rb +2 -7
- data/lib/action_dispatch/http/request.rb +12 -33
- data/lib/action_dispatch/http/response.rb +35 -15
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/http/url.rb +5 -32
- data/lib/action_dispatch/middleware/callbacks.rb +1 -1
- data/lib/action_dispatch/middleware/cookies.rb +4 -3
- data/lib/action_dispatch/middleware/params_parser.rb +4 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +51 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +6 -8
- data/lib/action_dispatch/middleware/show_exceptions.rb +0 -14
- data/lib/action_dispatch/middleware/stack.rb +6 -2
- data/lib/action_dispatch/railtie.rb +3 -1
- data/lib/action_dispatch/routing.rb +2 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +35 -7
- data/lib/action_dispatch/routing/mapper.rb +134 -48
- data/lib/action_dispatch/routing/route.rb +2 -2
- data/lib/action_dispatch/routing/route_set.rb +217 -158
- data/lib/action_dispatch/routing/url_for.rb +139 -0
- data/lib/action_dispatch/testing/assertions/response.rb +14 -61
- data/lib/action_dispatch/testing/assertions/routing.rb +25 -14
- data/lib/action_dispatch/testing/integration.rb +32 -50
- data/lib/action_dispatch/testing/performance_test.rb +3 -1
- data/lib/action_dispatch/testing/test_process.rb +2 -0
- data/lib/action_dispatch/testing/test_request.rb +2 -0
- data/lib/action_pack/version.rb +4 -3
- data/lib/action_view.rb +11 -6
- data/lib/action_view/base.rb +33 -121
- data/lib/action_view/context.rb +0 -2
- data/lib/action_view/helpers.rb +26 -23
- data/lib/action_view/helpers/active_model_helper.rb +28 -18
- data/lib/action_view/helpers/asset_tag_helper.rb +109 -54
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
- data/lib/action_view/helpers/cache_helper.rb +22 -1
- data/lib/action_view/helpers/capture_helper.rb +22 -22
- data/lib/action_view/helpers/date_helper.rb +6 -5
- data/lib/action_view/helpers/form_helper.rb +78 -63
- data/lib/action_view/helpers/form_options_helper.rb +6 -4
- data/lib/action_view/helpers/form_tag_helper.rb +26 -15
- data/lib/action_view/helpers/javascript_helper.rb +90 -10
- data/lib/action_view/helpers/number_helper.rb +315 -118
- data/lib/action_view/helpers/prototype_helper.rb +19 -46
- data/lib/action_view/helpers/record_tag_helper.rb +4 -4
- data/lib/action_view/helpers/tag_helper.rb +7 -24
- data/lib/action_view/helpers/text_helper.rb +8 -7
- data/lib/action_view/helpers/translation_helper.rb +7 -5
- data/lib/action_view/helpers/url_helper.rb +19 -16
- data/lib/action_view/locale/en.yml +45 -6
- data/lib/action_view/lookup_context.rb +190 -0
- data/lib/action_view/paths.rb +22 -63
- data/lib/action_view/railtie.rb +14 -4
- data/lib/action_view/railties/{subscriber.rb → log_subscriber.rb} +1 -1
- data/lib/action_view/render/layouts.rb +73 -0
- data/lib/action_view/render/partials.rb +15 -41
- data/lib/action_view/render/rendering.rb +27 -78
- data/lib/action_view/template.rb +20 -24
- data/lib/action_view/template/error.rb +22 -2
- data/lib/action_view/template/handlers/erb.rb +33 -9
- data/lib/action_view/template/handlers/rjs.rb +1 -2
- data/lib/action_view/template/resolver.rb +46 -104
- data/lib/action_view/template/text.rb +5 -12
- data/lib/action_view/test_case.rb +14 -23
- metadata +83 -40
- data/lib/abstract_controller/compatibility.rb +0 -18
- data/lib/abstract_controller/localized_cache.rb +0 -49
- data/lib/action_controller/metal/configuration.rb +0 -28
- data/lib/action_controller/url_rewriter.rb +0 -76
@@ -34,10 +34,12 @@ module ActionController
|
|
34
34
|
# and response object available. You might wish to control the
|
35
35
|
# environment and response manually for performance reasons.
|
36
36
|
|
37
|
-
attr_internal :
|
37
|
+
attr_internal :headers, :response, :request
|
38
|
+
delegate :session, :to => "@_request"
|
38
39
|
|
39
40
|
def initialize(*)
|
40
|
-
@_headers = {}
|
41
|
+
@_headers = {"Content-Type" => "text/html"}
|
42
|
+
@_status = 200
|
41
43
|
super
|
42
44
|
end
|
43
45
|
|
@@ -49,17 +51,35 @@ module ActionController
|
|
49
51
|
headers["Content-Type"] = type.to_s
|
50
52
|
end
|
51
53
|
|
54
|
+
def content_type
|
55
|
+
headers["Content-Type"]
|
56
|
+
end
|
57
|
+
|
58
|
+
def location
|
59
|
+
headers["Location"]
|
60
|
+
end
|
61
|
+
|
52
62
|
def location=(url)
|
53
63
|
headers["Location"] = url
|
54
64
|
end
|
55
65
|
|
66
|
+
def status
|
67
|
+
@_status
|
68
|
+
end
|
69
|
+
|
56
70
|
def status=(status)
|
57
71
|
@_status = Rack::Utils.status_code(status)
|
58
72
|
end
|
59
73
|
|
74
|
+
def response_body=(val)
|
75
|
+
body = val.respond_to?(:each) ? val : [val]
|
76
|
+
super body
|
77
|
+
end
|
78
|
+
|
60
79
|
# :api: private
|
61
|
-
def dispatch(name,
|
62
|
-
@
|
80
|
+
def dispatch(name, request)
|
81
|
+
@_request = request
|
82
|
+
@_env = request.env
|
63
83
|
@_env['action_controller.instance'] = self
|
64
84
|
process(name)
|
65
85
|
to_a
|
@@ -70,31 +90,12 @@ module ActionController
|
|
70
90
|
response ? response.to_a : [status, headers, response_body]
|
71
91
|
end
|
72
92
|
|
73
|
-
class ActionEndpoint
|
74
|
-
@@endpoints = Hash.new {|h,k| h[k] = Hash.new {|sh,sk| sh[sk] = {} } }
|
75
|
-
|
76
|
-
def self.for(controller, action, stack)
|
77
|
-
@@endpoints[controller][action][stack] ||= begin
|
78
|
-
endpoint = new(controller, action)
|
79
|
-
stack.build(endpoint)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def initialize(controller, action)
|
84
|
-
@controller, @action = controller, action
|
85
|
-
@_formats = [Mime::HTML]
|
86
|
-
end
|
87
|
-
|
88
|
-
def call(env)
|
89
|
-
@controller.new.dispatch(@action, env)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
93
|
class_attribute :middleware_stack
|
94
94
|
self.middleware_stack = ActionDispatch::MiddlewareStack.new
|
95
95
|
|
96
96
|
def self.inherited(base)
|
97
97
|
self.middleware_stack = base.middleware_stack.dup
|
98
|
+
super
|
98
99
|
end
|
99
100
|
|
100
101
|
def self.use(*args)
|
@@ -118,8 +119,10 @@ module ActionController
|
|
118
119
|
#
|
119
120
|
# ==== Returns
|
120
121
|
# Proc:: A rack application
|
121
|
-
def self.action(name)
|
122
|
-
|
122
|
+
def self.action(name, klass = ActionDispatch::Request)
|
123
|
+
middleware_stack.build do |env|
|
124
|
+
new.dispatch(name, klass.new(env))
|
125
|
+
end
|
123
126
|
end
|
124
127
|
end
|
125
128
|
end
|
@@ -2,26 +2,23 @@ module ActionController
|
|
2
2
|
module Compatibility
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
include AbstractController::Compatibility
|
6
|
-
|
7
5
|
class ::ActionController::ActionControllerError < StandardError #:nodoc:
|
8
6
|
end
|
9
7
|
|
8
|
+
module ClassMethods
|
9
|
+
end
|
10
|
+
|
10
11
|
# Temporary hax
|
11
12
|
included do
|
12
13
|
::ActionController::UnknownAction = ::AbstractController::ActionNotFound
|
13
14
|
::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
cattr_accessor :relative_url_root
|
19
|
-
self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
|
16
|
+
# ROUTES TODO: This should be handled by a middleware and route generation
|
17
|
+
# should be able to handle SCRIPT_NAME
|
18
|
+
self.config.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT']
|
20
19
|
|
21
20
|
class << self
|
22
21
|
delegate :default_charset=, :to => "ActionDispatch::Response"
|
23
|
-
delegate :resources_path_names, :to => "ActionController::Routing::Routes"
|
24
|
-
delegate :resources_path_names=, :to => "ActionController::Routing::Routes"
|
25
22
|
end
|
26
23
|
|
27
24
|
# cattr_reader :protected_instance_variables
|
@@ -32,84 +29,31 @@ module ActionController
|
|
32
29
|
@before_filter_chain_aborted @_headers @_params
|
33
30
|
@_response)
|
34
31
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
cattr_accessor :use_accept_header
|
40
|
-
self.use_accept_header = true
|
32
|
+
def rescue_action(env)
|
33
|
+
raise env["action_dispatch.rescue.exception"]
|
34
|
+
end
|
41
35
|
|
42
36
|
self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : ""
|
43
|
-
|
44
|
-
# Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets,
|
45
|
-
# and images to a dedicated asset server away from the main web server. Example:
|
46
|
-
# ActionController::Base.asset_host = "http://assets.example.com"
|
47
|
-
cattr_accessor :asset_host
|
48
|
-
|
49
|
-
cattr_accessor :ip_spoofing_check
|
50
|
-
self.ip_spoofing_check = true
|
51
|
-
|
52
|
-
cattr_accessor :trusted_proxies
|
53
37
|
end
|
54
38
|
|
55
39
|
# For old tests
|
56
40
|
def initialize_template_class(*) end
|
57
41
|
def assign_shortcuts(*) end
|
58
42
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
def process_action(*)
|
65
|
-
template
|
66
|
-
super
|
67
|
-
end
|
68
|
-
|
69
|
-
module ClassMethods
|
70
|
-
def consider_all_requests_local
|
71
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " <<
|
72
|
-
"use Rails.application.config.consider_all_requests_local instead"
|
73
|
-
Rails.application.config.consider_all_requests_local
|
74
|
-
end
|
75
|
-
|
76
|
-
def consider_all_requests_local=(value)
|
77
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is no longer effective. " <<
|
78
|
-
"Please configure it on your application with config.consider_all_requests_local="
|
79
|
-
end
|
80
|
-
|
81
|
-
def allow_concurrency
|
82
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " <<
|
83
|
-
"use Rails.application.config.allow_concurrency instead"
|
84
|
-
Rails.application.config.allow_concurrency
|
85
|
-
end
|
86
|
-
|
87
|
-
def allow_concurrency=(value)
|
88
|
-
ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is no longer effective. " <<
|
89
|
-
"Please configure it on your application with config.allow_concurrency="
|
90
|
-
end
|
91
|
-
|
92
|
-
def rescue_action(env)
|
93
|
-
raise env["action_dispatch.rescue.exception"]
|
94
|
-
end
|
95
|
-
|
96
|
-
# Defines the storage option for cached fragments
|
97
|
-
def cache_store=(store_option)
|
98
|
-
@@cache_store = ActiveSupport::Cache.lookup_store(store_option)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
delegate :consider_all_requests_local, :consider_all_requests_local=,
|
103
|
-
:allow_concurrency, :allow_concurrency=, :to => :"self.class"
|
104
|
-
|
105
|
-
def render_to_body(options)
|
106
|
-
if options.is_a?(Hash) && options.key?(:template)
|
107
|
-
options[:template].sub!(/^\//, '')
|
43
|
+
def _normalize_options(options)
|
44
|
+
if options[:action] && options[:action].to_s.include?(?/)
|
45
|
+
ActiveSupport::Deprecation.warn "Giving a path to render :action is deprecated. " <<
|
46
|
+
"Please use render :template instead", caller
|
47
|
+
options[:template] = options.delete(:action)
|
108
48
|
end
|
109
49
|
|
110
50
|
options[:text] = nil if options.delete(:nothing) == true
|
111
51
|
options[:text] = " " if options.key?(:text) && options[:text].nil?
|
52
|
+
super
|
53
|
+
end
|
112
54
|
|
55
|
+
def render_to_body(options)
|
56
|
+
options[:template].sub!(/^\//, '') if options.key?(:template)
|
113
57
|
super || " "
|
114
58
|
end
|
115
59
|
|
@@ -124,18 +68,5 @@ module ActionController
|
|
124
68
|
def performed?
|
125
69
|
response_body
|
126
70
|
end
|
127
|
-
|
128
|
-
# ==== Request only view path switching ====
|
129
|
-
def append_view_path(path)
|
130
|
-
view_paths.push(*path)
|
131
|
-
end
|
132
|
-
|
133
|
-
def prepend_view_path(path)
|
134
|
-
view_paths.unshift(*path)
|
135
|
-
end
|
136
|
-
|
137
|
-
def view_paths
|
138
|
-
view_context.view_paths
|
139
|
-
end
|
140
71
|
end
|
141
72
|
end
|
@@ -86,7 +86,7 @@ module ActionController
|
|
86
86
|
end
|
87
87
|
|
88
88
|
private
|
89
|
-
# Overwrite
|
89
|
+
# Overwrite modules_for_helpers to accept :all as argument, which loads
|
90
90
|
# all helpers in helpers_dir.
|
91
91
|
#
|
92
92
|
# ==== Parameters
|
@@ -95,7 +95,7 @@ module ActionController
|
|
95
95
|
# ==== Returns
|
96
96
|
# Array[Module]:: A normalized list of modules for the list of
|
97
97
|
# helpers provided.
|
98
|
-
def
|
98
|
+
def modules_for_helpers(args)
|
99
99
|
args += all_application_helpers if args.delete(:all)
|
100
100
|
super(args)
|
101
101
|
end
|
@@ -15,10 +15,8 @@ module ActionController
|
|
15
15
|
|
16
16
|
# Overrides AbstractController::Base#action_method? to return false if the
|
17
17
|
# action name is in the list of hidden actions.
|
18
|
-
def
|
19
|
-
self.class.visible_action?(action_name)
|
20
|
-
!self.class.hidden_actions.include?(action_name) && super
|
21
|
-
end
|
18
|
+
def method_for_action(action_name)
|
19
|
+
self.class.visible_action?(action_name) && super
|
22
20
|
end
|
23
21
|
|
24
22
|
module ClassMethods
|
@@ -31,13 +29,13 @@ module ActionController
|
|
31
29
|
end
|
32
30
|
|
33
31
|
def inherited(klass)
|
34
|
-
klass.
|
32
|
+
klass.class_eval { @visible_actions = {} }
|
35
33
|
super
|
36
34
|
end
|
37
35
|
|
38
36
|
def visible_action?(action_name)
|
39
37
|
return @visible_actions[action_name] if @visible_actions.key?(action_name)
|
40
|
-
@visible_actions[action_name] =
|
38
|
+
@visible_actions[action_name] = !hidden_actions.include?(action_name)
|
41
39
|
end
|
42
40
|
|
43
41
|
# Overrides AbstractController::Base#action_methods to remove any methods
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_support/base64'
|
2
|
+
require 'active_support/core_ext/object/blank'
|
2
3
|
|
3
4
|
module ActionController
|
4
5
|
module HttpAuthentication
|
@@ -124,7 +125,7 @@ module ActionController
|
|
124
125
|
end
|
125
126
|
|
126
127
|
def authenticate(request, &login_procedure)
|
127
|
-
unless
|
128
|
+
unless request.authorization.blank?
|
128
129
|
login_procedure.call(*user_name_and_password(request))
|
129
130
|
end
|
130
131
|
end
|
@@ -133,15 +134,8 @@ module ActionController
|
|
133
134
|
decode_credentials(request).split(/:/, 2)
|
134
135
|
end
|
135
136
|
|
136
|
-
def authorization(request)
|
137
|
-
request.env['HTTP_AUTHORIZATION'] ||
|
138
|
-
request.env['X-HTTP_AUTHORIZATION'] ||
|
139
|
-
request.env['X_HTTP_AUTHORIZATION'] ||
|
140
|
-
request.env['REDIRECT_X_HTTP_AUTHORIZATION']
|
141
|
-
end
|
142
|
-
|
143
137
|
def decode_credentials(request)
|
144
|
-
ActiveSupport::Base64.decode64(
|
138
|
+
ActiveSupport::Base64.decode64(request.authorization.split(' ', 2).last || '')
|
145
139
|
end
|
146
140
|
|
147
141
|
def encode_credentials(user_name, password)
|
@@ -165,7 +159,7 @@ module ActionController
|
|
165
159
|
|
166
160
|
# Authenticate with HTTP Digest, returns true or false
|
167
161
|
def authenticate_with_http_digest(realm = "Application", &password_procedure)
|
168
|
-
HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
|
162
|
+
HttpAuthentication::Digest.authenticate(config.secret, request, realm, &password_procedure)
|
169
163
|
end
|
170
164
|
|
171
165
|
# Render output including the HTTP Digest authentication header
|
@@ -175,30 +169,23 @@ module ActionController
|
|
175
169
|
end
|
176
170
|
|
177
171
|
# Returns false on a valid response, true otherwise
|
178
|
-
def authenticate(request, realm, &password_procedure)
|
179
|
-
authorization
|
180
|
-
end
|
181
|
-
|
182
|
-
def authorization(request)
|
183
|
-
request.env['HTTP_AUTHORIZATION'] ||
|
184
|
-
request.env['X-HTTP_AUTHORIZATION'] ||
|
185
|
-
request.env['X_HTTP_AUTHORIZATION'] ||
|
186
|
-
request.env['REDIRECT_X_HTTP_AUTHORIZATION']
|
172
|
+
def authenticate(secret_key, request, realm, &password_procedure)
|
173
|
+
request.authorization && validate_digest_response(secret_key, request, realm, &password_procedure)
|
187
174
|
end
|
188
175
|
|
189
176
|
# Returns false unless the request credentials response value matches the expected value.
|
190
177
|
# First try the password as a ha1 digest password. If this fails, then try it as a plain
|
191
178
|
# text password.
|
192
|
-
def validate_digest_response(request, realm, &password_procedure)
|
179
|
+
def validate_digest_response(secret_key, request, realm, &password_procedure)
|
193
180
|
credentials = decode_credentials_header(request)
|
194
|
-
valid_nonce = validate_nonce(request, credentials[:nonce])
|
181
|
+
valid_nonce = validate_nonce(secret_key, request, credentials[:nonce])
|
195
182
|
|
196
|
-
if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque]
|
183
|
+
if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque]
|
197
184
|
password = password_procedure.call(credentials[:username])
|
198
185
|
return false unless password
|
199
186
|
|
200
187
|
method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
|
201
|
-
uri = credentials[:uri][0,1] == '/' ? request.
|
188
|
+
uri = credentials[:uri][0,1] == '/' ? request.fullpath : request.url
|
202
189
|
|
203
190
|
[true, false].any? do |password_is_ha1|
|
204
191
|
expected = expected_response(method, uri, credentials, password, password_is_ha1)
|
@@ -226,7 +213,7 @@ module ActionController
|
|
226
213
|
end
|
227
214
|
|
228
215
|
def decode_credentials_header(request)
|
229
|
-
decode_credentials(authorization
|
216
|
+
decode_credentials(request.authorization)
|
230
217
|
end
|
231
218
|
|
232
219
|
def decode_credentials(header)
|
@@ -238,6 +225,9 @@ module ActionController
|
|
238
225
|
end
|
239
226
|
|
240
227
|
def authentication_header(controller, realm)
|
228
|
+
secret_key = controller.config.secret
|
229
|
+
nonce = self.nonce(secret_key)
|
230
|
+
opaque = opaque(secret_key)
|
241
231
|
controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}")
|
242
232
|
end
|
243
233
|
|
@@ -280,7 +270,7 @@ module ActionController
|
|
280
270
|
# The nonce is opaque to the client. Composed of Time, and hash of Time with secret
|
281
271
|
# key from the Rails session secret generated upon creation of project. Ensures
|
282
272
|
# the time cannot be modified by client.
|
283
|
-
def nonce(time = Time.now)
|
273
|
+
def nonce(secret_key, time = Time.now)
|
284
274
|
t = time.to_i
|
285
275
|
hashed = [t, secret_key]
|
286
276
|
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
|
@@ -292,21 +282,16 @@ module ActionController
|
|
292
282
|
# Can be much shorter if the Stale directive is implemented. This would
|
293
283
|
# allow a user to use new nonce without prompting user again for their
|
294
284
|
# username and password.
|
295
|
-
def validate_nonce(request, value, seconds_to_timeout=5*60)
|
285
|
+
def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60)
|
296
286
|
t = ActiveSupport::Base64.decode64(value).split(":").first.to_i
|
297
|
-
nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
|
287
|
+
nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout
|
298
288
|
end
|
299
289
|
|
300
290
|
# Opaque based on random generation - but changing each request?
|
301
|
-
def opaque()
|
291
|
+
def opaque(secret_key)
|
302
292
|
::Digest::MD5.hexdigest(secret_key)
|
303
293
|
end
|
304
294
|
|
305
|
-
# Set in /initializers/session_store.rb, and loaded even if sessions are not in use.
|
306
|
-
def secret_key
|
307
|
-
ActionController::Base.session_options[:secret]
|
308
|
-
end
|
309
|
-
|
310
295
|
end
|
311
296
|
end
|
312
297
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ActionController
|
2
|
+
module ImplicitRender
|
3
|
+
def send_action(*)
|
4
|
+
ret = super
|
5
|
+
default_render unless response_body
|
6
|
+
ret
|
7
|
+
end
|
8
|
+
|
9
|
+
def default_render
|
10
|
+
render
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_for_action(action_name)
|
14
|
+
super || begin
|
15
|
+
if template_exists?(action_name.to_s, _prefix)
|
16
|
+
"default_render"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|