activesupport 5.0.7.2 → 5.1.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +464 -694
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_support.rb +8 -4
- data/lib/active_support/all.rb +3 -3
- data/lib/active_support/array_inquirer.rb +7 -5
- data/lib/active_support/backtrace_cleaner.rb +4 -4
- data/lib/active_support/benchmarkable.rb +3 -3
- data/lib/active_support/builder.rb +1 -1
- data/lib/active_support/cache.rb +41 -48
- data/lib/active_support/cache/file_store.rb +11 -20
- data/lib/active_support/cache/mem_cache_store.rb +30 -40
- data/lib/active_support/cache/memory_store.rb +13 -13
- data/lib/active_support/cache/null_store.rb +4 -4
- data/lib/active_support/cache/strategy/local_cache.rb +13 -22
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +4 -5
- data/lib/active_support/callbacks.rb +649 -584
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
- data/lib/active_support/concurrency/share_lock.rb +20 -21
- data/lib/active_support/configurable.rb +5 -5
- data/lib/active_support/core_ext.rb +1 -2
- data/lib/active_support/core_ext/array.rb +7 -7
- data/lib/active_support/core_ext/array/access.rb +1 -1
- data/lib/active_support/core_ext/array/conversions.rb +15 -15
- data/lib/active_support/core_ext/array/grouping.rb +1 -1
- data/lib/active_support/core_ext/array/inquiry.rb +1 -1
- data/lib/active_support/core_ext/array/prepend_and_append.rb +1 -1
- data/lib/active_support/core_ext/benchmark.rb +1 -1
- data/lib/active_support/core_ext/big_decimal.rb +1 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +4 -6
- data/lib/active_support/core_ext/class.rb +2 -2
- data/lib/active_support/core_ext/class/attribute.rb +5 -5
- data/lib/active_support/core_ext/class/attribute_accessors.rb +1 -1
- data/lib/active_support/core_ext/class/subclasses.rb +18 -4
- data/lib/active_support/core_ext/date.rb +5 -5
- data/lib/active_support/core_ext/date/acts_like.rb +1 -1
- data/lib/active_support/core_ext/date/blank.rb +1 -1
- data/lib/active_support/core_ext/date/calculations.rb +8 -8
- data/lib/active_support/core_ext/date/conversions.rb +12 -12
- data/lib/active_support/core_ext/date/zones.rb +2 -2
- data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -22
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +7 -8
- data/lib/active_support/core_ext/date_time.rb +5 -5
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -2
- data/lib/active_support/core_ext/date_time/blank.rb +1 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +20 -10
- data/lib/active_support/core_ext/date_time/compatibility.rb +2 -2
- data/lib/active_support/core_ext/date_time/conversions.rb +12 -12
- data/lib/active_support/core_ext/digest/uuid.rb +4 -4
- data/lib/active_support/core_ext/enumerable.rb +23 -12
- data/lib/active_support/core_ext/file.rb +1 -1
- data/lib/active_support/core_ext/file/atomic.rb +4 -4
- data/lib/active_support/core_ext/hash.rb +9 -9
- data/lib/active_support/core_ext/hash/compact.rb +12 -9
- data/lib/active_support/core_ext/hash/conversions.rb +36 -37
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -2
- data/lib/active_support/core_ext/hash/keys.rb +6 -6
- data/lib/active_support/core_ext/hash/reverse_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/slice.rb +4 -4
- data/lib/active_support/core_ext/hash/transform_values.rb +1 -0
- data/lib/active_support/core_ext/integer.rb +3 -3
- data/lib/active_support/core_ext/integer/inflections.rb +1 -1
- data/lib/active_support/core_ext/integer/time.rb +2 -2
- data/lib/active_support/core_ext/kernel.rb +4 -4
- data/lib/active_support/core_ext/kernel/concern.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +1 -1
- data/lib/active_support/core_ext/load_error.rb +1 -18
- data/lib/active_support/core_ext/module.rb +11 -12
- data/lib/active_support/core_ext/module/aliasing.rb +3 -48
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -4
- data/lib/active_support/core_ext/module/attribute_accessors.rb +11 -5
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +20 -13
- data/lib/active_support/core_ext/module/concerning.rb +1 -1
- data/lib/active_support/core_ext/module/delegation.rb +85 -16
- data/lib/active_support/core_ext/module/introspection.rb +3 -11
- data/lib/active_support/core_ext/module/reachable.rb +2 -2
- data/lib/active_support/core_ext/numeric.rb +4 -4
- data/lib/active_support/core_ext/numeric/conversions.rb +3 -9
- data/lib/active_support/core_ext/numeric/inquiry.rb +21 -21
- data/lib/active_support/core_ext/numeric/time.rb +5 -5
- data/lib/active_support/core_ext/object.rb +12 -12
- data/lib/active_support/core_ext/object/blank.rb +3 -1
- data/lib/active_support/core_ext/object/conversions.rb +4 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
- data/lib/active_support/core_ext/object/duplicable.rb +34 -4
- data/lib/active_support/core_ext/object/inclusion.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +26 -12
- data/lib/active_support/core_ext/object/to_param.rb +1 -1
- data/lib/active_support/core_ext/object/to_query.rb +8 -5
- data/lib/active_support/core_ext/object/try.rb +1 -1
- data/lib/active_support/core_ext/object/with_options.rb +12 -1
- data/lib/active_support/core_ext/range.rb +4 -4
- data/lib/active_support/core_ext/range/conversions.rb +1 -1
- data/lib/active_support/core_ext/regexp.rb +4 -0
- data/lib/active_support/core_ext/securerandom.rb +3 -3
- data/lib/active_support/core_ext/string.rb +13 -13
- data/lib/active_support/core_ext/string/access.rb +6 -6
- data/lib/active_support/core_ext/string/conversions.rb +2 -2
- data/lib/active_support/core_ext/string/filters.rb +3 -3
- data/lib/active_support/core_ext/string/indent.rb +4 -4
- data/lib/active_support/core_ext/string/inflections.rb +10 -14
- data/lib/active_support/core_ext/string/inquiry.rb +1 -1
- data/lib/active_support/core_ext/string/multibyte.rb +1 -1
- data/lib/active_support/core_ext/string/output_safety.rb +19 -20
- data/lib/active_support/core_ext/string/strip.rb +1 -1
- data/lib/active_support/core_ext/string/zones.rb +2 -2
- data/lib/active_support/core_ext/time.rb +5 -5
- data/lib/active_support/core_ext/time/acts_like.rb +1 -1
- data/lib/active_support/core_ext/time/calculations.rb +46 -29
- data/lib/active_support/core_ext/time/conversions.rb +15 -12
- data/lib/active_support/core_ext/time/zones.rb +3 -3
- data/lib/active_support/core_ext/uri.rb +2 -2
- data/lib/active_support/dependencies.rb +45 -46
- data/lib/active_support/dependencies/interlock.rb +1 -1
- data/lib/active_support/deprecation.rb +9 -8
- data/lib/active_support/deprecation/behaviors.rb +3 -3
- data/lib/active_support/deprecation/constant_accessor.rb +50 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -2
- data/lib/active_support/deprecation/method_wrappers.rb +10 -3
- data/lib/active_support/deprecation/proxy_wrappers.rb +6 -4
- data/lib/active_support/deprecation/reporting.rb +7 -7
- data/lib/active_support/duration.rb +221 -28
- data/lib/active_support/duration/iso8601_parser.rb +66 -65
- data/lib/active_support/duration/iso8601_serializer.rb +11 -9
- data/lib/active_support/evented_file_update_checker.rb +59 -55
- data/lib/active_support/execution_wrapper.rb +3 -3
- data/lib/active_support/executor.rb +1 -1
- data/lib/active_support/file_update_checker.rb +54 -50
- data/lib/active_support/gem_version.rb +2 -2
- data/lib/active_support/gzip.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +40 -28
- data/lib/active_support/i18n.rb +5 -5
- data/lib/active_support/i18n_railtie.rb +14 -9
- data/lib/active_support/inflections.rb +11 -11
- data/lib/active_support/inflector.rb +5 -5
- data/lib/active_support/inflector/inflections.rb +11 -9
- data/lib/active_support/inflector/methods.rb +52 -51
- data/lib/active_support/inflector/transliterate.rb +8 -11
- data/lib/active_support/json.rb +2 -2
- data/lib/active_support/json/decoding.rb +3 -3
- data/lib/active_support/json/encoding.rb +8 -7
- data/lib/active_support/key_generator.rb +17 -17
- data/lib/active_support/lazy_load_hooks.rb +2 -2
- data/lib/active_support/log_subscriber.rb +9 -7
- data/lib/active_support/log_subscriber/test_helper.rb +9 -9
- data/lib/active_support/logger.rb +3 -3
- data/lib/active_support/logger_silence.rb +3 -3
- data/lib/active_support/logger_thread_safe_level.rb +1 -1
- data/lib/active_support/message_encryptor.rb +77 -35
- data/lib/active_support/message_verifier.rb +7 -7
- data/lib/active_support/multibyte.rb +2 -2
- data/lib/active_support/multibyte/chars.rb +23 -21
- data/lib/active_support/multibyte/unicode.rb +68 -89
- data/lib/active_support/notifications.rb +7 -5
- data/lib/active_support/notifications/fanout.rb +3 -3
- data/lib/active_support/notifications/instrumenter.rb +5 -5
- data/lib/active_support/number_helper.rb +5 -4
- data/lib/active_support/number_helper/number_converter.rb +11 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -3
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +8 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -11
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -3
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -32
- data/lib/active_support/number_helper/rounding_helper.rb +64 -0
- data/lib/active_support/option_merger.rb +1 -1
- data/lib/active_support/ordered_hash.rb +3 -3
- data/lib/active_support/ordered_options.rb +6 -4
- data/lib/active_support/per_thread_registry.rb +5 -5
- data/lib/active_support/rails.rb +12 -6
- data/lib/active_support/railtie.rb +3 -3
- data/lib/active_support/reloader.rb +1 -1
- data/lib/active_support/rescuable.rb +6 -6
- data/lib/active_support/security_utils.rb +1 -1
- data/lib/active_support/string_inquirer.rb +8 -2
- data/lib/active_support/subscriber.rb +9 -5
- data/lib/active_support/tagged_logging.rb +4 -4
- data/lib/active_support/test_case.rb +12 -29
- data/lib/active_support/testing/assertions.rb +100 -2
- data/lib/active_support/testing/autorun.rb +2 -2
- data/lib/active_support/testing/constant_lookup.rb +0 -1
- data/lib/active_support/testing/declarative.rb +1 -1
- data/lib/active_support/testing/deprecation.rb +3 -2
- data/lib/active_support/testing/isolation.rb +15 -22
- data/lib/active_support/testing/method_call_assertions.rb +1 -1
- data/lib/active_support/testing/setup_and_teardown.rb +2 -2
- data/lib/active_support/testing/stream.rb +28 -28
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +45 -11
- data/lib/active_support/time.rb +12 -12
- data/lib/active_support/time_with_zone.rb +16 -14
- data/lib/active_support/values/time_zone.rb +100 -31
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +1 -1
- data/lib/active_support/xml_mini.rb +34 -36
- data/lib/active_support/xml_mini/jdom.rb +112 -112
- data/lib/active_support/xml_mini/libxml.rb +12 -11
- data/lib/active_support/xml_mini/libxmlsax.rb +13 -14
- data/lib/active_support/xml_mini/nokogiri.rb +10 -10
- data/lib/active_support/xml_mini/nokogirisax.rb +12 -13
- data/lib/active_support/xml_mini/rexml.rb +9 -9
- metadata +8 -9
- data/lib/active_support/concurrency/latch.rb +0 -26
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -3
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -3
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -70
- data/lib/active_support/core_ext/struct.rb +0 -3
- data/lib/active_support/core_ext/time/marshal.rb +0 -3
@@ -1,9 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "active_support/core_ext/string/multibyte"
|
2
|
+
require "active_support/i18n"
|
3
3
|
|
4
4
|
module ActiveSupport
|
5
5
|
module Inflector
|
6
|
-
|
7
6
|
# Replaces non-ASCII characters with an ASCII approximation, or if none
|
8
7
|
# exists, a replacement character which defaults to "?".
|
9
8
|
#
|
@@ -58,9 +57,11 @@ module ActiveSupport
|
|
58
57
|
# transliterate('Jürgen')
|
59
58
|
# # => "Juergen"
|
60
59
|
def transliterate(string, replacement = "?".freeze)
|
60
|
+
raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
|
61
|
+
|
61
62
|
I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
|
62
63
|
ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
|
63
|
-
:
|
64
|
+
replacement: replacement)
|
64
65
|
end
|
65
66
|
|
66
67
|
# Replaces special characters in a string so that it may be used as part of
|
@@ -79,11 +80,7 @@ module ActiveSupport
|
|
79
80
|
# parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
|
80
81
|
# parameterize("^trés|Jolie-- ", preserve_case: true) # => "tres-Jolie"
|
81
82
|
#
|
82
|
-
def parameterize(string,
|
83
|
-
unless sep == :unused
|
84
|
-
ActiveSupport::Deprecation.warn("Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '#{sep}'` instead.")
|
85
|
-
separator = sep
|
86
|
-
end
|
83
|
+
def parameterize(string, separator: "-", preserve_case: false)
|
87
84
|
# Replace accented chars with their ASCII equivalents.
|
88
85
|
parameterized_string = transliterate(string)
|
89
86
|
|
@@ -102,9 +99,9 @@ module ActiveSupport
|
|
102
99
|
# No more than one of the separator in a row.
|
103
100
|
parameterized_string.gsub!(re_duplicate_separator, separator)
|
104
101
|
# Remove leading/trailing separator.
|
105
|
-
parameterized_string.gsub!(re_leading_trailing_separator,
|
102
|
+
parameterized_string.gsub!(re_leading_trailing_separator, "".freeze)
|
106
103
|
end
|
107
|
-
|
104
|
+
|
108
105
|
parameterized_string.downcase! unless preserve_case
|
109
106
|
parameterized_string
|
110
107
|
end
|
data/lib/active_support/json.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "active_support/json/decoding"
|
2
|
+
require "active_support/json/encoding"
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
2
|
+
require "active_support/core_ext/module/delegation"
|
3
|
+
require "json"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
# Look for and parse json strings that look like ISO 8601 times.
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "active_support/core_ext/object/json"
|
2
|
+
require "active_support/core_ext/module/delegation"
|
3
3
|
|
4
4
|
module ActiveSupport
|
5
5
|
class << self
|
@@ -7,7 +7,7 @@ module ActiveSupport
|
|
7
7
|
:time_precision, :time_precision=,
|
8
8
|
:escape_html_entities_in_json, :escape_html_entities_in_json=,
|
9
9
|
:json_encoder, :json_encoder=,
|
10
|
-
:
|
10
|
+
to: :'ActiveSupport::JSON::Encoding'
|
11
11
|
end
|
12
12
|
|
13
13
|
module JSON
|
@@ -40,9 +40,9 @@ module ActiveSupport
|
|
40
40
|
ESCAPED_CHARS = {
|
41
41
|
"\u2028" => '\u2028',
|
42
42
|
"\u2029" => '\u2029',
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
">" => '\u003e',
|
44
|
+
"<" => '\u003c',
|
45
|
+
"&" => '\u0026',
|
46
46
|
}
|
47
47
|
|
48
48
|
ESCAPE_REGEX_WITH_HTML_ENTITIES = /[\u2028\u2029><&]/u
|
@@ -68,7 +68,8 @@ module ActiveSupport
|
|
68
68
|
:ESCAPE_REGEX_WITHOUT_HTML_ENTITIES, :EscapedString
|
69
69
|
|
70
70
|
# Convert an object into a "JSON-ready" representation composed of
|
71
|
-
# primitives like Hash, Array, String, Numeric,
|
71
|
+
# primitives like Hash, Array, String, Numeric,
|
72
|
+
# and +true+/+false+/+nil+.
|
72
73
|
# Recursively calls #as_json to the object to recursively build a
|
73
74
|
# fully JSON-ready object.
|
74
75
|
#
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "concurrent/map"
|
2
|
+
require "openssl"
|
3
3
|
|
4
4
|
module ActiveSupport
|
5
5
|
# KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2.
|
@@ -17,7 +17,7 @@ module ActiveSupport
|
|
17
17
|
# Returns a derived key suitable for use. The default key_size is chosen
|
18
18
|
# to be compatible with the default settings of ActiveSupport::MessageVerifier.
|
19
19
|
# i.e. OpenSSL::Digest::SHA1#block_length
|
20
|
-
def generate_key(salt, key_size=64)
|
20
|
+
def generate_key(salt, key_size = 64)
|
21
21
|
OpenSSL::PKCS5.pbkdf2_hmac_sha1(@secret, salt, @iterations, key_size)
|
22
22
|
end
|
23
23
|
end
|
@@ -51,21 +51,21 @@ module ActiveSupport
|
|
51
51
|
|
52
52
|
private
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
54
|
+
# To prevent users from using something insecure like "Password" we make sure that the
|
55
|
+
# secret they've provided is at least 30 characters in length.
|
56
|
+
def ensure_secret_secure(secret)
|
57
|
+
if secret.blank?
|
58
|
+
raise ArgumentError, "A secret is required to generate an integrity hash " \
|
59
|
+
"for cookie session data. Set a secret_key_base of at least " \
|
60
|
+
"#{SECRET_MIN_LENGTH} characters in config/secrets.yml."
|
61
|
+
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
if secret.length < SECRET_MIN_LENGTH
|
64
|
+
raise ArgumentError, "Secret should be something secure, " \
|
65
|
+
"like \"#{SecureRandom.hex(16)}\". The value you " \
|
66
|
+
"provided, \"#{secret}\", is shorter than the minimum length " \
|
67
|
+
"of #{SECRET_MIN_LENGTH} characters."
|
68
|
+
end
|
68
69
|
end
|
69
|
-
end
|
70
70
|
end
|
71
71
|
end
|
@@ -15,9 +15,9 @@ module ActiveSupport
|
|
15
15
|
# end
|
16
16
|
# end
|
17
17
|
#
|
18
|
-
# When the entirety of +
|
18
|
+
# When the entirety of +ActiveRecord::Base+ has been
|
19
19
|
# evaluated then +run_load_hooks+ is invoked. The very last line of
|
20
|
-
# +
|
20
|
+
# +ActiveRecord::Base+ is:
|
21
21
|
#
|
22
22
|
# ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
|
23
23
|
module LazyLoadHooks
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "active_support/core_ext/module/attribute_accessors"
|
2
|
+
require "active_support/core_ext/class/attribute"
|
3
|
+
require "active_support/subscriber"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
# ActiveSupport::LogSubscriber is an object set to consume
|
@@ -81,11 +81,13 @@ module ActiveSupport
|
|
81
81
|
|
82
82
|
def finish(name, id, payload)
|
83
83
|
super if logger
|
84
|
-
rescue
|
85
|
-
logger
|
84
|
+
rescue => e
|
85
|
+
if logger
|
86
|
+
logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}"
|
87
|
+
end
|
86
88
|
end
|
87
89
|
|
88
|
-
|
90
|
+
private
|
89
91
|
|
90
92
|
%w(info debug warn error fatal unknown).each do |level|
|
91
93
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
@@ -99,7 +101,7 @@ module ActiveSupport
|
|
99
101
|
# option is set to +true+, it also adds bold to the string. This is based
|
100
102
|
# on the Highline implementation and will automatically append CLEAR to the
|
101
103
|
# end of the returned String.
|
102
|
-
def color(text, color, bold=false)
|
104
|
+
def color(text, color, bold = false) # :doc:
|
103
105
|
return text unless colorize_logging
|
104
106
|
color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
|
105
107
|
bold = bold ? BOLD : ""
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "active_support/log_subscriber"
|
2
|
+
require "active_support/logger"
|
3
|
+
require "active_support/notifications"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
class LogSubscriber
|
@@ -58,15 +58,15 @@ module ActiveSupport
|
|
58
58
|
def initialize(level = DEBUG)
|
59
59
|
@flush_count = 0
|
60
60
|
@level = level
|
61
|
-
@logged = Hash.new { |h,k| h[k] = [] }
|
61
|
+
@logged = Hash.new { |h, k| h[k] = [] }
|
62
62
|
end
|
63
63
|
|
64
64
|
def method_missing(level, message = nil)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
65
|
+
if block_given?
|
66
|
+
@logged[level] << yield
|
67
|
+
else
|
68
|
+
@logged[level] << message
|
69
|
+
end
|
70
70
|
end
|
71
71
|
|
72
72
|
def logged(level)
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "active_support/logger_silence"
|
2
|
+
require "active_support/logger_thread_safe_level"
|
3
|
+
require "logger"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
class Logger < ::Logger
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "active_support/concern"
|
2
|
+
require "active_support/core_ext/module/attribute_accessors"
|
3
|
+
require "concurrent"
|
4
4
|
|
5
5
|
module LoggerSilence
|
6
6
|
extend ActiveSupport::Concern
|
@@ -1,6 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "openssl"
|
2
|
+
require "base64"
|
3
|
+
require "active_support/core_ext/array/extract_options"
|
4
|
+
require "active_support/message_verifier"
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
# MessageEncryptor is a simple way to encrypt values which get stored
|
@@ -30,6 +31,16 @@ module ActiveSupport
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
34
|
+
module NullVerifier #:nodoc:
|
35
|
+
def self.verify(value)
|
36
|
+
value
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.generate(value)
|
40
|
+
value
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
33
44
|
class InvalidMessage < StandardError; end
|
34
45
|
OpenSSLCipherError = OpenSSL::Cipher::CipherError
|
35
46
|
|
@@ -39,18 +50,25 @@ module ActiveSupport
|
|
39
50
|
# key by using <tt>ActiveSupport::KeyGenerator</tt> or a similar key
|
40
51
|
# derivation function.
|
41
52
|
#
|
53
|
+
# First additional parameter is used as the signature key for +MessageVerifier+.
|
54
|
+
# This allows you to specify keys to encrypt and sign data.
|
55
|
+
#
|
56
|
+
# ActiveSupport::MessageEncryptor.new('secret', 'signature_secret')
|
57
|
+
#
|
42
58
|
# Options:
|
43
59
|
# * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by
|
44
60
|
# <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'.
|
45
|
-
# * <tt>:digest</tt> - String of digest to use for signing. Default is
|
61
|
+
# * <tt>:digest</tt> - String of digest to use for signing. Default is
|
62
|
+
# +SHA1+. Ignored when using an AEAD cipher like 'aes-256-gcm'.
|
46
63
|
# * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
|
47
64
|
def initialize(secret, *signature_key_or_options)
|
48
65
|
options = signature_key_or_options.extract_options!
|
49
66
|
sign_secret = signature_key_or_options.first
|
50
67
|
@secret = secret
|
51
68
|
@sign_secret = sign_secret
|
52
|
-
@cipher = options[:cipher] ||
|
53
|
-
@
|
69
|
+
@cipher = options[:cipher] || DEFAULT_CIPHER
|
70
|
+
@digest = options[:digest] || "SHA1" unless aead_mode?
|
71
|
+
@verifier = resolve_verifier
|
54
72
|
@serializer = options[:serializer] || Marshal
|
55
73
|
end
|
56
74
|
|
@@ -73,42 +91,66 @@ module ActiveSupport
|
|
73
91
|
|
74
92
|
private
|
75
93
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
# Rely on OpenSSL for the initialization vector
|
82
|
-
iv = cipher.random_iv
|
94
|
+
def _encrypt(value)
|
95
|
+
cipher = new_cipher
|
96
|
+
cipher.encrypt
|
97
|
+
cipher.key = @secret
|
83
98
|
|
84
|
-
|
85
|
-
|
99
|
+
# Rely on OpenSSL for the initialization vector
|
100
|
+
iv = cipher.random_iv
|
101
|
+
cipher.auth_data = "" if aead_mode?
|
86
102
|
|
87
|
-
|
88
|
-
|
103
|
+
encrypted_data = cipher.update(@serializer.dump(value))
|
104
|
+
encrypted_data << cipher.final
|
89
105
|
|
90
|
-
|
91
|
-
|
92
|
-
|
106
|
+
blob = "#{::Base64.strict_encode64 encrypted_data}--#{::Base64.strict_encode64 iv}"
|
107
|
+
blob << "--#{::Base64.strict_encode64 cipher.auth_tag}" if aead_mode?
|
108
|
+
blob
|
109
|
+
end
|
93
110
|
|
94
|
-
|
95
|
-
|
96
|
-
|
111
|
+
def _decrypt(encrypted_message)
|
112
|
+
cipher = new_cipher
|
113
|
+
encrypted_data, iv, auth_tag = encrypted_message.split("--".freeze).map { |v| ::Base64.strict_decode64(v) }
|
114
|
+
|
115
|
+
# Currently the OpenSSL bindings do not raise an error if auth_tag is
|
116
|
+
# truncated, which would allow an attacker to easily forge it. See
|
117
|
+
# https://github.com/ruby/openssl/issues/63
|
118
|
+
raise InvalidMessage if aead_mode? && (auth_tag.nil? || auth_tag.bytes.length != 16)
|
119
|
+
|
120
|
+
cipher.decrypt
|
121
|
+
cipher.key = @secret
|
122
|
+
cipher.iv = iv
|
123
|
+
if aead_mode?
|
124
|
+
cipher.auth_tag = auth_tag
|
125
|
+
cipher.auth_data = ""
|
126
|
+
end
|
127
|
+
|
128
|
+
decrypted_data = cipher.update(encrypted_data)
|
129
|
+
decrypted_data << cipher.final
|
130
|
+
|
131
|
+
@serializer.load(decrypted_data)
|
132
|
+
rescue OpenSSLCipherError, TypeError, ArgumentError
|
133
|
+
raise InvalidMessage
|
134
|
+
end
|
97
135
|
|
98
|
-
|
99
|
-
|
136
|
+
def new_cipher
|
137
|
+
OpenSSL::Cipher.new(@cipher)
|
138
|
+
end
|
100
139
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
140
|
+
def verifier
|
141
|
+
@verifier
|
142
|
+
end
|
105
143
|
|
106
|
-
|
107
|
-
|
108
|
-
|
144
|
+
def aead_mode?
|
145
|
+
@aead_mode ||= new_cipher.authenticated?
|
146
|
+
end
|
109
147
|
|
110
|
-
|
111
|
-
|
112
|
-
|
148
|
+
def resolve_verifier
|
149
|
+
if aead_mode?
|
150
|
+
NullVerifier
|
151
|
+
else
|
152
|
+
MessageVerifier.new(@sign_secret || @secret, digest: @digest, serializer: NullSerializer)
|
153
|
+
end
|
154
|
+
end
|
113
155
|
end
|
114
156
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "base64"
|
2
|
+
require "active_support/core_ext/object/blank"
|
3
|
+
require "active_support/security_utils"
|
4
4
|
|
5
5
|
module ActiveSupport
|
6
6
|
# +MessageVerifier+ makes it easy to generate and verify messages which are
|
@@ -34,9 +34,9 @@ module ActiveSupport
|
|
34
34
|
class InvalidSignature < StandardError; end
|
35
35
|
|
36
36
|
def initialize(secret, options = {})
|
37
|
-
raise ArgumentError,
|
37
|
+
raise ArgumentError, "Secret should not be nil." unless secret
|
38
38
|
@secret = secret
|
39
|
-
@digest = options[:digest] ||
|
39
|
+
@digest = options[:digest] || "SHA1"
|
40
40
|
@serializer = options[:serializer] || Marshal
|
41
41
|
end
|
42
42
|
|
@@ -83,7 +83,7 @@ module ActiveSupport
|
|
83
83
|
data = signed_message.split("--".freeze)[0]
|
84
84
|
@serializer.load(decode(data))
|
85
85
|
rescue ArgumentError => argument_error
|
86
|
-
return if argument_error.message
|
86
|
+
return if argument_error.message.include?("invalid base64")
|
87
87
|
raise
|
88
88
|
end
|
89
89
|
end
|
@@ -127,7 +127,7 @@ module ActiveSupport
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def generate_digest(data)
|
130
|
-
require
|
130
|
+
require "openssl" unless defined?(OpenSSL)
|
131
131
|
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@digest).new, @secret, data)
|
132
132
|
end
|
133
133
|
end
|