actionpack 5.2.2 → 5.2.4.5
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 +82 -0
- data/lib/action_controller/metal.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +2 -2
- data/lib/action_controller/metal/request_forgery_protection.rb +29 -4
- data/lib/action_controller/metal/strong_parameters.rb +2 -0
- data/lib/action_controller/test_case.rb +5 -4
- data/lib/action_dispatch.rb +5 -4
- data/lib/action_dispatch/http/cache.rb +6 -4
- data/lib/action_dispatch/http/mime_negotiation.rb +5 -0
- data/lib/action_dispatch/journey/path/pattern.rb +2 -1
- data/lib/action_dispatch/middleware/session/abstract_store.rb +14 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +11 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +21 -10
- data/lib/action_dispatch/middleware/stack.rb +2 -2
- data/lib/action_dispatch/request/session.rb +7 -1
- data/lib/action_pack/gem_version.rb +2 -2
- metadata +17 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8458248b602da029b1e9113db9f0305888fdf99bf83ea4fe679ad0ed49b22175
|
4
|
+
data.tar.gz: '085825f1ed9d286aa92cf5fa06fb039534331030d5b70da304c237a492f7ded9'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7a6b62b3afeeb992a981128fbfab64944e897f20a0e75cbef6fd3d972108321ff440f7344935c8d196c1d1e6d3e08d64f040c6c5aa9ad63f06e9b78875da0c54
|
7
|
+
data.tar.gz: 27a049710288451664d3672a6fb18fe505003d9bb91826408ab507d9de06fa9f1a877a2dfc6b9a9b91e32c0f122cdfd33b1bcd3802e64966e4388c17dcad08e6
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,57 @@
|
|
1
|
+
## Rails 5.2.4.5 (February 10, 2021) ##
|
2
|
+
|
3
|
+
* No changes.
|
4
|
+
|
5
|
+
|
6
|
+
## Rails 5.2.4.4 (September 09, 2020) ##
|
7
|
+
|
8
|
+
* No changes.
|
9
|
+
|
10
|
+
|
11
|
+
## Rails 5.2.4.3 (May 18, 2020) ##
|
12
|
+
|
13
|
+
* [CVE-2020-8166] HMAC raw CSRF token before masking it, so it cannot be used to reconstruct a per-form token
|
14
|
+
|
15
|
+
* [CVE-2020-8164] Return self when calling #each, #each_pair, and #each_value instead of the raw @parameters hash
|
16
|
+
|
17
|
+
|
18
|
+
## Rails 5.2.4.1 (December 18, 2019) ##
|
19
|
+
|
20
|
+
* Fix possible information leak / session hijacking vulnerability.
|
21
|
+
|
22
|
+
The `ActionDispatch::Session::MemcacheStore` is still vulnerable given it requires the
|
23
|
+
gem dalli to be updated as well.
|
24
|
+
|
25
|
+
CVE-2019-16782.
|
26
|
+
|
27
|
+
|
28
|
+
## Rails 5.2.4 (November 27, 2019) ##
|
29
|
+
|
30
|
+
* No changes.
|
31
|
+
|
32
|
+
|
33
|
+
## Rails 5.2.3 (March 27, 2019) ##
|
34
|
+
|
35
|
+
* Allow using `public` and `no-cache` together in the the Cache Control header.
|
36
|
+
|
37
|
+
Before this change, even if `public` was specified in the Cache Control header,
|
38
|
+
it was excluded when `no-cache` was included. This change preserves the
|
39
|
+
`public` value as is.
|
40
|
+
|
41
|
+
Fixes #34780.
|
42
|
+
|
43
|
+
*Yuji Yaginuma*
|
44
|
+
|
45
|
+
* Allow `nil` params for `ActionController::TestCase`.
|
46
|
+
|
47
|
+
*Ryo Nakamura*
|
48
|
+
|
49
|
+
|
50
|
+
## Rails 5.2.2.1 (March 11, 2019) ##
|
51
|
+
|
52
|
+
* No changes.
|
53
|
+
|
54
|
+
|
1
55
|
## Rails 5.2.2 (December 04, 2018) ##
|
2
56
|
|
3
57
|
* Reset Capybara sessions if failed system test screenshot raising an exception.
|
@@ -164,6 +218,34 @@
|
|
164
218
|
|
165
219
|
* Matches behavior of `Hash#each` in `ActionController::Parameters#each`.
|
166
220
|
|
221
|
+
Rails 5.0 introduced a bug when looping through controller params using `each`. Only the keys of params hash were passed to the block, e.g.
|
222
|
+
|
223
|
+
# Parameters: {"param"=>"1", "param_two"=>"2"}
|
224
|
+
def index
|
225
|
+
params.each do |name|
|
226
|
+
puts name
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
# Prints
|
231
|
+
# param
|
232
|
+
# param_two
|
233
|
+
|
234
|
+
In Rails 5.2 the bug has been fixed and name will be an array (which was the behavior for all versions prior to 5.0), instead of a string.
|
235
|
+
|
236
|
+
To fix the code above simply change as per example below:
|
237
|
+
|
238
|
+
# Parameters: {"param"=>"1", "param_two"=>"2"}
|
239
|
+
def index
|
240
|
+
params.each do |name, value|
|
241
|
+
puts name
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
# Prints
|
246
|
+
# param
|
247
|
+
# param_two
|
248
|
+
|
167
249
|
*Dominic Cleal*
|
168
250
|
|
169
251
|
* Add `Referrer-Policy` header to default headers set.
|
@@ -26,10 +26,10 @@ module ActionController
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
def build(action, app =
|
29
|
+
def build(action, app = nil, &block)
|
30
30
|
action = action.to_s
|
31
31
|
|
32
|
-
middlewares.reverse.inject(app) do |a, middleware|
|
32
|
+
middlewares.reverse.inject(app || block) do |a, middleware|
|
33
33
|
middleware.valid?(action) ? middleware.build(a) : a
|
34
34
|
end
|
35
35
|
end
|
@@ -93,7 +93,7 @@ module ActionController
|
|
93
93
|
end
|
94
94
|
|
95
95
|
def model
|
96
|
-
super ||
|
96
|
+
super || self.model = _default_wrap_model
|
97
97
|
end
|
98
98
|
|
99
99
|
def include
|
@@ -115,7 +115,7 @@ module ActionController
|
|
115
115
|
|
116
116
|
if m.respond_to?(:nested_attributes_options) && m.nested_attributes_options.keys.any?
|
117
117
|
self.include += m.nested_attributes_options.keys.map do |key|
|
118
|
-
key.to_s.concat("_attributes")
|
118
|
+
key.to_s.dup.concat("_attributes")
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
@@ -318,13 +318,15 @@ module ActionController #:nodoc:
|
|
318
318
|
action_path = normalize_action_path(action)
|
319
319
|
per_form_csrf_token(session, action_path, method)
|
320
320
|
else
|
321
|
-
|
321
|
+
global_csrf_token(session)
|
322
322
|
end
|
323
323
|
|
324
324
|
one_time_pad = SecureRandom.random_bytes(AUTHENTICITY_TOKEN_LENGTH)
|
325
325
|
encrypted_csrf_token = xor_byte_strings(one_time_pad, raw_token)
|
326
326
|
masked_token = one_time_pad + encrypted_csrf_token
|
327
|
-
Base64.
|
327
|
+
Base64.urlsafe_encode64(masked_token, padding: false)
|
328
|
+
|
329
|
+
mask_token(raw_token)
|
328
330
|
end
|
329
331
|
|
330
332
|
# Checks the client's masked token to see if it matches the
|
@@ -354,7 +356,8 @@ module ActionController #:nodoc:
|
|
354
356
|
elsif masked_token.length == AUTHENTICITY_TOKEN_LENGTH * 2
|
355
357
|
csrf_token = unmask_token(masked_token)
|
356
358
|
|
357
|
-
|
359
|
+
compare_with_global_token(csrf_token, session) ||
|
360
|
+
compare_with_real_token(csrf_token, session) ||
|
358
361
|
valid_per_form_csrf_token?(csrf_token, session)
|
359
362
|
else
|
360
363
|
false # Token is malformed.
|
@@ -369,10 +372,21 @@ module ActionController #:nodoc:
|
|
369
372
|
xor_byte_strings(one_time_pad, encrypted_csrf_token)
|
370
373
|
end
|
371
374
|
|
375
|
+
def mask_token(raw_token) # :doc:
|
376
|
+
one_time_pad = SecureRandom.random_bytes(AUTHENTICITY_TOKEN_LENGTH)
|
377
|
+
encrypted_csrf_token = xor_byte_strings(one_time_pad, raw_token)
|
378
|
+
masked_token = one_time_pad + encrypted_csrf_token
|
379
|
+
Base64.strict_encode64(masked_token)
|
380
|
+
end
|
381
|
+
|
372
382
|
def compare_with_real_token(token, session) # :doc:
|
373
383
|
ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, real_csrf_token(session))
|
374
384
|
end
|
375
385
|
|
386
|
+
def compare_with_global_token(token, session) # :doc:
|
387
|
+
ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, global_csrf_token(session))
|
388
|
+
end
|
389
|
+
|
376
390
|
def valid_per_form_csrf_token?(token, session) # :doc:
|
377
391
|
if per_form_csrf_tokens
|
378
392
|
correct_token = per_form_csrf_token(
|
@@ -393,10 +407,21 @@ module ActionController #:nodoc:
|
|
393
407
|
end
|
394
408
|
|
395
409
|
def per_form_csrf_token(session, action_path, method) # :doc:
|
410
|
+
csrf_token_hmac(session, [action_path, method.downcase].join("#"))
|
411
|
+
end
|
412
|
+
|
413
|
+
GLOBAL_CSRF_TOKEN_IDENTIFIER = "!real_csrf_token"
|
414
|
+
private_constant :GLOBAL_CSRF_TOKEN_IDENTIFIER
|
415
|
+
|
416
|
+
def global_csrf_token(session) # :doc:
|
417
|
+
csrf_token_hmac(session, GLOBAL_CSRF_TOKEN_IDENTIFIER)
|
418
|
+
end
|
419
|
+
|
420
|
+
def csrf_token_hmac(session, identifier) # :doc:
|
396
421
|
OpenSSL::HMAC.digest(
|
397
422
|
OpenSSL::Digest::SHA256.new,
|
398
423
|
real_csrf_token(session),
|
399
|
-
|
424
|
+
identifier
|
400
425
|
)
|
401
426
|
end
|
402
427
|
|
@@ -457,9 +457,10 @@ module ActionController
|
|
457
457
|
# respectively which will make tests more expressive.
|
458
458
|
#
|
459
459
|
# Note that the request method is not verified.
|
460
|
-
def process(action, method: "GET", params:
|
460
|
+
def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil)
|
461
461
|
check_required_ivars
|
462
462
|
|
463
|
+
action = action.to_s.dup
|
463
464
|
http_method = method.to_s.upcase
|
464
465
|
|
465
466
|
@html_document = nil
|
@@ -485,17 +486,17 @@ module ActionController
|
|
485
486
|
format ||= as
|
486
487
|
end
|
487
488
|
|
488
|
-
parameters = params.symbolize_keys
|
489
|
+
parameters = (params || {}).symbolize_keys
|
489
490
|
|
490
491
|
if format
|
491
492
|
parameters[:format] = format
|
492
493
|
end
|
493
494
|
|
494
|
-
generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action
|
495
|
+
generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action))
|
495
496
|
generated_path = generated_path(generated_extras)
|
496
497
|
query_string_keys = query_parameter_names(generated_extras)
|
497
498
|
|
498
|
-
@request.assign_parameters(@routes, controller_class_name, action
|
499
|
+
@request.assign_parameters(@routes, controller_class_name, action, parameters, generated_path, query_string_keys)
|
499
500
|
|
500
501
|
@request.session.update(session) if session
|
501
502
|
@request.flash.update(flash || {})
|
data/lib/action_dispatch.rb
CHANGED
@@ -83,10 +83,11 @@ module ActionDispatch
|
|
83
83
|
end
|
84
84
|
|
85
85
|
module Session
|
86
|
-
autoload :AbstractStore,
|
87
|
-
autoload :
|
88
|
-
autoload :
|
89
|
-
autoload :
|
86
|
+
autoload :AbstractStore, "action_dispatch/middleware/session/abstract_store"
|
87
|
+
autoload :AbstractSecureStore, "action_dispatch/middleware/session/abstract_store"
|
88
|
+
autoload :CookieStore, "action_dispatch/middleware/session/cookie_store"
|
89
|
+
autoload :MemCacheStore, "action_dispatch/middleware/session/mem_cache_store"
|
90
|
+
autoload :CacheStore, "action_dispatch/middleware/session/cache_store"
|
90
91
|
end
|
91
92
|
|
92
93
|
mattr_accessor :test_app
|
@@ -197,10 +197,12 @@ module ActionDispatch
|
|
197
197
|
if control.empty?
|
198
198
|
# Let middleware handle default behavior
|
199
199
|
elsif control[:no_cache]
|
200
|
-
|
201
|
-
if control[:
|
202
|
-
|
203
|
-
|
200
|
+
options = []
|
201
|
+
options << PUBLIC if control[:public]
|
202
|
+
options << NO_CACHE
|
203
|
+
options.concat(control[:extras]) if control[:extras]
|
204
|
+
|
205
|
+
self._cache_control = options.join(", ")
|
204
206
|
else
|
205
207
|
extras = control[:extras]
|
206
208
|
max_age = control[:max_age]
|
@@ -83,7 +83,21 @@ module ActionDispatch
|
|
83
83
|
include SessionObject
|
84
84
|
|
85
85
|
private
|
86
|
+
def set_cookie(request, session_id, cookie)
|
87
|
+
request.cookie_jar[key] = cookie
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class AbstractSecureStore < Rack::Session::Abstract::PersistedSecure
|
92
|
+
include Compatibility
|
93
|
+
include StaleSessionCheck
|
94
|
+
include SessionObject
|
95
|
+
|
96
|
+
def generate_sid
|
97
|
+
Rack::Session::SessionId.new(super)
|
98
|
+
end
|
86
99
|
|
100
|
+
private
|
87
101
|
def set_cookie(request, session_id, cookie)
|
88
102
|
request.cookie_jar[key] = cookie
|
89
103
|
end
|
@@ -12,7 +12,7 @@ module ActionDispatch
|
|
12
12
|
# * <tt>cache</tt> - The cache to use. If it is not specified, <tt>Rails.cache</tt> will be used.
|
13
13
|
# * <tt>expire_after</tt> - The length of time a session will be stored before automatically expiring.
|
14
14
|
# By default, the <tt>:expires_in</tt> option of the cache is used.
|
15
|
-
class CacheStore <
|
15
|
+
class CacheStore < AbstractSecureStore
|
16
16
|
def initialize(app, options = {})
|
17
17
|
@cache = options[:cache] || Rails.cache
|
18
18
|
options[:expire_after] ||= @cache.options[:expires_in]
|
@@ -21,7 +21,7 @@ module ActionDispatch
|
|
21
21
|
|
22
22
|
# Get a session from the cache.
|
23
23
|
def find_session(env, sid)
|
24
|
-
unless sid && (session =
|
24
|
+
unless sid && (session = get_session_with_fallback(sid))
|
25
25
|
sid, session = generate_sid, {}
|
26
26
|
end
|
27
27
|
[sid, session]
|
@@ -29,7 +29,7 @@ module ActionDispatch
|
|
29
29
|
|
30
30
|
# Set a session in the cache.
|
31
31
|
def write_session(env, sid, session, options)
|
32
|
-
key = cache_key(sid)
|
32
|
+
key = cache_key(sid.private_id)
|
33
33
|
if session
|
34
34
|
@cache.write(key, session, expires_in: options[:expire_after])
|
35
35
|
else
|
@@ -40,14 +40,19 @@ module ActionDispatch
|
|
40
40
|
|
41
41
|
# Remove a session from the cache.
|
42
42
|
def delete_session(env, sid, options)
|
43
|
-
@cache.delete(cache_key(sid))
|
43
|
+
@cache.delete(cache_key(sid.private_id))
|
44
|
+
@cache.delete(cache_key(sid.public_id))
|
44
45
|
generate_sid
|
45
46
|
end
|
46
47
|
|
47
48
|
private
|
48
49
|
# Turn the session id into a cache key.
|
49
|
-
def cache_key(
|
50
|
-
"_session_id:#{
|
50
|
+
def cache_key(id)
|
51
|
+
"_session_id:#{id}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_session_with_fallback(sid)
|
55
|
+
@cache.read(cache_key(sid.private_id)) || @cache.read(cache_key(sid.public_id))
|
51
56
|
end
|
52
57
|
end
|
53
58
|
end
|
@@ -29,9 +29,10 @@ module ActionDispatch
|
|
29
29
|
#
|
30
30
|
# Rails.application.config.session_store :cookie_store, key: '_your_app_session'
|
31
31
|
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# encrypted in the
|
32
|
+
# In the development and test environments your application's secret key base is
|
33
|
+
# generated by Rails and stored in a temporary file in <tt>tmp/development_secret.txt</tt>.
|
34
|
+
# In all other environments, it is stored encrypted in the
|
35
|
+
# <tt>config/credentials.yml.enc</tt> file.
|
35
36
|
#
|
36
37
|
# If your application was not updated to Rails 5.2 defaults, the secret_key_base
|
37
38
|
# will be found in the old <tt>config/secrets.yml</tt> file.
|
@@ -50,7 +51,16 @@ module ActionDispatch
|
|
50
51
|
# would set the session cookie to expire automatically 14 days after creation.
|
51
52
|
# Other useful options include <tt>:key</tt>, <tt>:secure</tt> and
|
52
53
|
# <tt>:httponly</tt>.
|
53
|
-
class CookieStore <
|
54
|
+
class CookieStore < AbstractSecureStore
|
55
|
+
class SessionId < DelegateClass(Rack::Session::SessionId)
|
56
|
+
attr_reader :cookie_value
|
57
|
+
|
58
|
+
def initialize(session_id, cookie_value = {})
|
59
|
+
super(session_id)
|
60
|
+
@cookie_value = cookie_value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
54
64
|
def initialize(app, options = {})
|
55
65
|
super(app, options.merge!(cookie_only: true))
|
56
66
|
end
|
@@ -58,7 +68,7 @@ module ActionDispatch
|
|
58
68
|
def delete_session(req, session_id, options)
|
59
69
|
new_sid = generate_sid unless options[:drop]
|
60
70
|
# Reset hash and Assign the new session id
|
61
|
-
req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid } : {})
|
71
|
+
req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid.public_id } : {})
|
62
72
|
new_sid
|
63
73
|
end
|
64
74
|
|
@@ -66,7 +76,7 @@ module ActionDispatch
|
|
66
76
|
stale_session_check! do
|
67
77
|
data = unpacked_cookie_data(req)
|
68
78
|
data = persistent_session_id!(data)
|
69
|
-
[data["session_id"], data]
|
79
|
+
[Rack::Session::SessionId.new(data["session_id"]), data]
|
70
80
|
end
|
71
81
|
end
|
72
82
|
|
@@ -74,7 +84,8 @@ module ActionDispatch
|
|
74
84
|
|
75
85
|
def extract_session_id(req)
|
76
86
|
stale_session_check! do
|
77
|
-
unpacked_cookie_data(req)["session_id"]
|
87
|
+
sid = unpacked_cookie_data(req)["session_id"]
|
88
|
+
sid && Rack::Session::SessionId.new(sid)
|
78
89
|
end
|
79
90
|
end
|
80
91
|
|
@@ -92,13 +103,13 @@ module ActionDispatch
|
|
92
103
|
|
93
104
|
def persistent_session_id!(data, sid = nil)
|
94
105
|
data ||= {}
|
95
|
-
data["session_id"] ||= sid || generate_sid
|
106
|
+
data["session_id"] ||= sid || generate_sid.public_id
|
96
107
|
data
|
97
108
|
end
|
98
109
|
|
99
110
|
def write_session(req, sid, session_data, options)
|
100
|
-
session_data["session_id"] = sid
|
101
|
-
session_data
|
111
|
+
session_data["session_id"] = sid.public_id
|
112
|
+
SessionId.new(sid, session_data)
|
102
113
|
end
|
103
114
|
|
104
115
|
def set_cookie(request, session_id, cookie)
|
@@ -97,8 +97,8 @@ module ActionDispatch
|
|
97
97
|
middlewares.push(build_middleware(klass, args, block))
|
98
98
|
end
|
99
99
|
|
100
|
-
def build(app =
|
101
|
-
middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) }
|
100
|
+
def build(app = nil, &block)
|
101
|
+
middlewares.freeze.reverse.inject(app || block) { |a, e| e.build(a) }
|
102
102
|
end
|
103
103
|
|
104
104
|
private
|
@@ -90,7 +90,13 @@ module ActionDispatch
|
|
90
90
|
# +nil+ if the given key is not found in the session.
|
91
91
|
def [](key)
|
92
92
|
load_for_read!
|
93
|
-
|
93
|
+
key = key.to_s
|
94
|
+
|
95
|
+
if key == "session_id"
|
96
|
+
id&.public_id
|
97
|
+
else
|
98
|
+
@delegate[key]
|
99
|
+
end
|
94
100
|
end
|
95
101
|
|
96
102
|
# Returns true if the session has the given key or false.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.2.
|
4
|
+
version: 5.2.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 5.2.
|
19
|
+
version: 5.2.4.5
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 5.2.
|
26
|
+
version: 5.2.4.5
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -31,6 +31,9 @@ dependencies:
|
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '2.0'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 2.0.8
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,6 +41,9 @@ dependencies:
|
|
38
41
|
- - "~>"
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '2.0'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.0.8
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: rack-test
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,28 +98,28 @@ dependencies:
|
|
92
98
|
requirements:
|
93
99
|
- - '='
|
94
100
|
- !ruby/object:Gem::Version
|
95
|
-
version: 5.2.
|
101
|
+
version: 5.2.4.5
|
96
102
|
type: :runtime
|
97
103
|
prerelease: false
|
98
104
|
version_requirements: !ruby/object:Gem::Requirement
|
99
105
|
requirements:
|
100
106
|
- - '='
|
101
107
|
- !ruby/object:Gem::Version
|
102
|
-
version: 5.2.
|
108
|
+
version: 5.2.4.5
|
103
109
|
- !ruby/object:Gem::Dependency
|
104
110
|
name: activemodel
|
105
111
|
requirement: !ruby/object:Gem::Requirement
|
106
112
|
requirements:
|
107
113
|
- - '='
|
108
114
|
- !ruby/object:Gem::Version
|
109
|
-
version: 5.2.
|
115
|
+
version: 5.2.4.5
|
110
116
|
type: :development
|
111
117
|
prerelease: false
|
112
118
|
version_requirements: !ruby/object:Gem::Requirement
|
113
119
|
requirements:
|
114
120
|
- - '='
|
115
121
|
- !ruby/object:Gem::Version
|
116
|
-
version: 5.2.
|
122
|
+
version: 5.2.4.5
|
117
123
|
description: Web apps on Rails. Simple, battle-tested conventions for building and
|
118
124
|
testing MVC web applications. Works with any Rack-compatible server.
|
119
125
|
email: david@loudthinking.com
|
@@ -293,8 +299,8 @@ homepage: http://rubyonrails.org
|
|
293
299
|
licenses:
|
294
300
|
- MIT
|
295
301
|
metadata:
|
296
|
-
source_code_uri: https://github.com/rails/rails/tree/v5.2.
|
297
|
-
changelog_uri: https://github.com/rails/rails/blob/v5.2.
|
302
|
+
source_code_uri: https://github.com/rails/rails/tree/v5.2.4.5/actionpack
|
303
|
+
changelog_uri: https://github.com/rails/rails/blob/v5.2.4.5/actionpack/CHANGELOG.md
|
298
304
|
post_install_message:
|
299
305
|
rdoc_options: []
|
300
306
|
require_paths:
|
@@ -311,8 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
311
317
|
version: '0'
|
312
318
|
requirements:
|
313
319
|
- none
|
314
|
-
|
315
|
-
rubygems_version: 2.7.6
|
320
|
+
rubygems_version: 3.0.3
|
316
321
|
signing_key:
|
317
322
|
specification_version: 4
|
318
323
|
summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).
|