activesupport 5.0.0 → 6.1.0
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 +5 -5
- data/CHANGELOG.md +343 -590
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -4
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +11 -5
- data/lib/active_support/backtrace_cleaner.rb +33 -5
- data/lib/active_support/benchmarkable.rb +5 -3
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +45 -53
- data/lib/active_support/cache/mem_cache_store.rb +81 -79
- data/lib/active_support/cache/memory_store.rb +69 -41
- data/lib/active_support/cache/null_store.rb +11 -4
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +74 -37
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +332 -161
- data/lib/active_support/callbacks.rb +657 -586
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +59 -19
- data/lib/active_support/configurable.rb +15 -17
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +20 -18
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +3 -1
- data/lib/active_support/core_ext/array/inquiry.rb +3 -1
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +9 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +6 -6
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +18 -26
- data/lib/active_support/core_ext/class.rb +4 -2
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +3 -1
- data/lib/active_support/core_ext/date/calculations.rb +16 -13
- data/lib/active_support/core_ext/date/conversions.rb +23 -21
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +7 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +82 -53
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -5
- data/lib/active_support/core_ext/date_and_time/zones.rb +9 -9
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +3 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +23 -11
- data/lib/active_support/core_ext/date_time/compatibility.rb +15 -2
- data/lib/active_support/core_ext/date_time/conversions.rb +14 -13
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +165 -29
- data/lib/active_support/core_ext/file/atomic.rb +7 -5
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +40 -39
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -2
- data/lib/active_support/core_ext/hash/keys.rb +9 -36
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +10 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +3 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +3 -1
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +2 -23
- data/lib/active_support/core_ext/marshal.rb +6 -2
- data/lib/active_support/core_ext/module/aliasing.rb +5 -48
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +7 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +53 -59
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +31 -24
- data/lib/active_support/core_ext/module/concerning.rb +16 -11
- data/lib/active_support/core_ext/module/delegation.rb +159 -44
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +23 -26
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +13 -12
- data/lib/active_support/core_ext/name_error.rb +36 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -134
- data/lib/active_support/core_ext/numeric/time.rb +18 -26
- data/lib/active_support/core_ext/numeric.rb +5 -4
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +14 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +4 -2
- data/lib/active_support/core_ext/object/duplicable.rb +13 -62
- data/lib/active_support/core_ext/object/inclusion.rb +3 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +42 -15
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +20 -8
- data/lib/active_support/core_ext/object/with_options.rb +15 -2
- data/lib/active_support/core_ext/object.rb +14 -12
- data/lib/active_support/core_ext/range/compare_range.rb +82 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/each.rb +5 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +10 -1
- data/lib/active_support/core_ext/securerandom.rb +28 -6
- data/lib/active_support/core_ext/string/access.rb +9 -18
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +5 -2
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +47 -4
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +78 -29
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +10 -5
- data/lib/active_support/core_ext/string/output_safety.rb +86 -31
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +117 -45
- data/lib/active_support/core_ext/time/compatibility.rb +13 -2
- data/lib/active_support/core_ext/time/conversions.rb +18 -12
- data/lib/active_support/core_ext/time/zones.rb +9 -7
- data/lib/active_support/core_ext/time.rb +7 -5
- data/lib/active_support/core_ext/uri.rb +12 -7
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +208 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +7 -1
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +172 -98
- data/lib/active_support/deprecation/behaviors.rb +45 -13
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +32 -17
- data/lib/active_support/deprecation/proxy_wrappers.rb +35 -7
- data/lib/active_support/deprecation/reporting.rb +61 -16
- data/lib/active_support/deprecation.rb +17 -9
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +67 -66
- data/lib/active_support/duration/iso8601_serializer.rb +25 -17
- data/lib/active_support/duration.rb +349 -46
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +88 -112
- data/lib/active_support/execution_wrapper.rb +25 -13
- data/lib/active_support/executor.rb +3 -1
- data/lib/active_support/file_update_checker.rb +56 -51
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +4 -2
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +153 -49
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +30 -20
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +28 -15
- data/lib/active_support/inflector/methods.rb +120 -109
- data/lib/active_support/inflector/transliterate.rb +60 -25
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +30 -29
- data/lib/active_support/json/encoding.rb +22 -11
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +6 -36
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber/test_helper.rb +11 -9
- data/lib/active_support/log_subscriber.rb +51 -18
- data/lib/active_support/logger.rb +9 -22
- data/lib/active_support/logger_silence.rb +14 -21
- data/lib/active_support/logger_thread_safe_level.rb +55 -8
- data/lib/active_support/message_encryptor.rb +170 -53
- data/lib/active_support/message_verifier.rb +91 -20
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +24 -78
- data/lib/active_support/multibyte/unicode.rb +21 -352
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +121 -19
- data/lib/active_support/notifications/instrumenter.rb +78 -14
- data/lib/active_support/notifications.rb +80 -12
- data/lib/active_support/number_helper/number_converter.rb +17 -16
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -12
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -13
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +18 -55
- data/lib/active_support/number_helper/rounding_helper.rb +50 -0
- data/lib/active_support/number_helper.rb +45 -16
- data/lib/active_support/option_merger.rb +25 -4
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +23 -9
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +7 -5
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +8 -9
- data/lib/active_support/railtie.rb +62 -11
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +20 -11
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +26 -15
- data/lib/active_support/string_inquirer.rb +12 -3
- data/lib/active_support/subscriber.rb +77 -23
- data/lib/active_support/tagged_logging.rb +52 -17
- data/lib/active_support/test_case.rb +106 -29
- data/lib/active_support/testing/assertions.rb +144 -8
- data/lib/active_support/testing/autorun.rb +5 -10
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +4 -2
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +19 -24
- data/lib/active_support/testing/method_call_assertions.rb +31 -2
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +30 -29
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +125 -24
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +142 -55
- data/lib/active_support/values/time_zone.rb +160 -53
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +115 -114
- data/lib/active_support/xml_mini/libxml.rb +15 -14
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +13 -13
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +18 -9
- data/lib/active_support/xml_mini.rb +44 -42
- data/lib/active_support.rb +19 -10
- metadata +79 -37
- data/lib/active_support/concurrency/latch.rb +0 -19
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -20
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -29
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- 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/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/core_ext/struct.rb +0 -3
- data/lib/active_support/core_ext/time/marshal.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/object/duplicable"
|
4
|
+
|
5
|
+
module ActiveSupport
|
6
|
+
# +ParameterFilter+ allows you to specify keys for sensitive data from
|
7
|
+
# hash-like object and replace corresponding value. Filtering only certain
|
8
|
+
# sub-keys from a hash is possible by using the dot notation:
|
9
|
+
# 'credit_card.number'. If a proc is given, each key and value of a hash and
|
10
|
+
# all sub-hashes are passed to it, where the value or the key can be replaced
|
11
|
+
# using String#replace or similar methods.
|
12
|
+
#
|
13
|
+
# ActiveSupport::ParameterFilter.new([:password])
|
14
|
+
# => replaces the value to all keys matching /password/i with "[FILTERED]"
|
15
|
+
#
|
16
|
+
# ActiveSupport::ParameterFilter.new([:foo, "bar"])
|
17
|
+
# => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
|
18
|
+
#
|
19
|
+
# ActiveSupport::ParameterFilter.new(["credit_card.code"])
|
20
|
+
# => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
|
21
|
+
# change { file: { code: "xxxx"} }
|
22
|
+
#
|
23
|
+
# ActiveSupport::ParameterFilter.new([-> (k, v) do
|
24
|
+
# v.reverse! if /secret/i.match?(k)
|
25
|
+
# end])
|
26
|
+
# => reverses the value to all keys matching /secret/i
|
27
|
+
class ParameterFilter
|
28
|
+
FILTERED = "[FILTERED]" # :nodoc:
|
29
|
+
|
30
|
+
# Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+.
|
31
|
+
# Other types of filters are treated as +String+ using +to_s+.
|
32
|
+
# For +Proc+ filters, key, value, and optional original hash is passed to block arguments.
|
33
|
+
#
|
34
|
+
# ==== Options
|
35
|
+
#
|
36
|
+
# * <tt>:mask</tt> - A replaced object when filtered. Defaults to +"[FILTERED]"+
|
37
|
+
def initialize(filters = [], mask: FILTERED)
|
38
|
+
@filters = filters
|
39
|
+
@mask = mask
|
40
|
+
end
|
41
|
+
|
42
|
+
# Mask value of +params+ if key matches one of filters.
|
43
|
+
def filter(params)
|
44
|
+
compiled_filter.call(params)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns filtered value for given key. For +Proc+ filters, third block argument is not populated.
|
48
|
+
def filter_param(key, value)
|
49
|
+
@filters.empty? ? value : compiled_filter.value_for_key(key, value)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def compiled_filter
|
54
|
+
@compiled_filter ||= CompiledFilter.compile(@filters, mask: @mask)
|
55
|
+
end
|
56
|
+
|
57
|
+
class CompiledFilter # :nodoc:
|
58
|
+
def self.compile(filters, mask:)
|
59
|
+
return lambda { |params| params.dup } if filters.empty?
|
60
|
+
|
61
|
+
strings, regexps, blocks, deep_regexps, deep_strings = [], [], [], nil, nil
|
62
|
+
|
63
|
+
filters.each do |item|
|
64
|
+
case item
|
65
|
+
when Proc
|
66
|
+
blocks << item
|
67
|
+
when Regexp
|
68
|
+
if item.to_s.include?("\\.")
|
69
|
+
(deep_regexps ||= []) << item
|
70
|
+
else
|
71
|
+
regexps << item
|
72
|
+
end
|
73
|
+
else
|
74
|
+
s = Regexp.escape(item.to_s)
|
75
|
+
if s.include?("\\.")
|
76
|
+
(deep_strings ||= []) << s
|
77
|
+
else
|
78
|
+
strings << s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
regexps << Regexp.new(strings.join("|"), true) unless strings.empty?
|
84
|
+
(deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings&.any?
|
85
|
+
|
86
|
+
new regexps, deep_regexps, blocks, mask: mask
|
87
|
+
end
|
88
|
+
|
89
|
+
attr_reader :regexps, :deep_regexps, :blocks
|
90
|
+
|
91
|
+
def initialize(regexps, deep_regexps, blocks, mask:)
|
92
|
+
@regexps = regexps
|
93
|
+
@deep_regexps = deep_regexps&.any? ? deep_regexps : nil
|
94
|
+
@blocks = blocks
|
95
|
+
@mask = mask
|
96
|
+
end
|
97
|
+
|
98
|
+
def call(params, parents = [], original_params = params)
|
99
|
+
filtered_params = params.class.new
|
100
|
+
|
101
|
+
params.each do |key, value|
|
102
|
+
filtered_params[key] = value_for_key(key, value, parents, original_params)
|
103
|
+
end
|
104
|
+
|
105
|
+
filtered_params
|
106
|
+
end
|
107
|
+
|
108
|
+
def value_for_key(key, value, parents = [], original_params = nil)
|
109
|
+
parents.push(key) if deep_regexps
|
110
|
+
if regexps.any? { |r| r.match?(key.to_s) }
|
111
|
+
value = @mask
|
112
|
+
elsif deep_regexps && (joined = parents.join(".")) && deep_regexps.any? { |r| r.match?(joined) }
|
113
|
+
value = @mask
|
114
|
+
elsif value.is_a?(Hash)
|
115
|
+
value = call(value, parents, original_params)
|
116
|
+
elsif value.is_a?(Array)
|
117
|
+
# If we don't pop the current parent it will be duplicated as we
|
118
|
+
# process each array value.
|
119
|
+
parents.pop if deep_regexps
|
120
|
+
value = value.map { |v| value_for_key(key, v, parents, original_params) }
|
121
|
+
# Restore the parent stack after processing the array.
|
122
|
+
parents.push(key) if deep_regexps
|
123
|
+
elsif blocks.any?
|
124
|
+
key = key.dup if key.duplicable?
|
125
|
+
value = value.dup if value.duplicable?
|
126
|
+
blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) }
|
127
|
+
end
|
128
|
+
parents.pop if deep_regexps
|
129
|
+
value
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/delegation"
|
2
4
|
|
3
5
|
module ActiveSupport
|
4
|
-
# NOTE: This approach has been deprecated for end-user code in favor of thread_mattr_accessor and friends.
|
6
|
+
# NOTE: This approach has been deprecated for end-user code in favor of {thread_mattr_accessor}[rdoc-ref:Module#thread_mattr_accessor] and friends.
|
5
7
|
# Please use that approach instead.
|
6
8
|
#
|
7
9
|
# This module is used to encapsulate access to thread local variables.
|
@@ -38,15 +40,15 @@ module ActiveSupport
|
|
38
40
|
# If the class has an initializer, it must accept no arguments.
|
39
41
|
module PerThreadRegistry
|
40
42
|
def self.extended(object)
|
41
|
-
object.instance_variable_set
|
43
|
+
object.instance_variable_set :@per_thread_registry_key, object.name.freeze
|
42
44
|
end
|
43
45
|
|
44
46
|
def instance
|
45
47
|
Thread.current[@per_thread_registry_key] ||= new
|
46
48
|
end
|
47
49
|
|
48
|
-
|
49
|
-
def method_missing(name, *args, &block)
|
50
|
+
private
|
51
|
+
def method_missing(name, *args, &block)
|
50
52
|
# Caches the method definition as a singleton method of the receiver.
|
51
53
|
#
|
52
54
|
# By letting #delegate handle it, we avoid an enclosure that'll capture args.
|
data/lib/active_support/rails.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This is a private interface.
|
2
4
|
#
|
3
5
|
# Rails components cherry pick from Active Support as needed, but there are a
|
4
6
|
# few features that are used for sure in some way or another and it is not worth
|
@@ -9,19 +11,16 @@
|
|
9
11
|
# Rails and can change anytime.
|
10
12
|
|
11
13
|
# Defines Object#blank? and Object#present?.
|
12
|
-
require
|
13
|
-
|
14
|
-
# Rails own autoload, eager_load, etc.
|
15
|
-
require 'active_support/dependencies/autoload'
|
14
|
+
require "active_support/core_ext/object/blank"
|
16
15
|
|
17
16
|
# Support for ClassMethods and the included macro.
|
18
|
-
require
|
17
|
+
require "active_support/concern"
|
19
18
|
|
20
19
|
# Defines Class#class_attribute.
|
21
|
-
require
|
20
|
+
require "active_support/core_ext/class/attribute"
|
22
21
|
|
23
22
|
# Defines Module#delegate.
|
24
|
-
require
|
23
|
+
require "active_support/core_ext/module/delegation"
|
25
24
|
|
26
25
|
# Defines ActiveSupport::Deprecation.
|
27
|
-
require
|
26
|
+
require "active_support/deprecation"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support"
|
2
4
|
require "active_support/i18n_railtie"
|
3
5
|
|
@@ -7,10 +9,38 @@ module ActiveSupport
|
|
7
9
|
|
8
10
|
config.eager_load_namespaces << ActiveSupport
|
9
11
|
|
12
|
+
initializer "active_support.set_authenticated_message_encryption" do |app|
|
13
|
+
config.after_initialize do
|
14
|
+
unless app.config.active_support.use_authenticated_message_encryption.nil?
|
15
|
+
ActiveSupport::MessageEncryptor.use_authenticated_message_encryption =
|
16
|
+
app.config.active_support.use_authenticated_message_encryption
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
initializer "active_support.reset_all_current_attributes_instances" do |app|
|
22
|
+
app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all }
|
23
|
+
app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all }
|
24
|
+
app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all }
|
25
|
+
|
26
|
+
ActiveSupport.on_load(:active_support_test_case) do
|
27
|
+
require "active_support/current_attributes/test_helper"
|
28
|
+
include ActiveSupport::CurrentAttributes::TestHelper
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
10
32
|
initializer "active_support.deprecation_behavior" do |app|
|
11
33
|
if deprecation = app.config.active_support.deprecation
|
12
34
|
ActiveSupport::Deprecation.behavior = deprecation
|
13
35
|
end
|
36
|
+
|
37
|
+
if disallowed_deprecation = app.config.active_support.disallowed_deprecation
|
38
|
+
ActiveSupport::Deprecation.disallowed_behavior = disallowed_deprecation
|
39
|
+
end
|
40
|
+
|
41
|
+
if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings
|
42
|
+
ActiveSupport::Deprecation.disallowed_warnings = disallowed_warnings
|
43
|
+
end
|
14
44
|
end
|
15
45
|
|
16
46
|
# Sets the default value for Time.zone
|
@@ -21,30 +51,51 @@ module ActiveSupport
|
|
21
51
|
rescue TZInfo::DataSourceNotFound => e
|
22
52
|
raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install"
|
23
53
|
end
|
24
|
-
require
|
25
|
-
zone_default = Time.find_zone!(app.config.time_zone)
|
26
|
-
|
27
|
-
unless zone_default
|
28
|
-
raise 'Value assigned to config.time_zone not recognized. ' \
|
29
|
-
'Run "rake time:zones:all" for a time zone names list.'
|
30
|
-
end
|
31
|
-
|
32
|
-
Time.zone_default = zone_default
|
54
|
+
require "active_support/core_ext/time/zones"
|
55
|
+
Time.zone_default = Time.find_zone!(app.config.time_zone)
|
33
56
|
end
|
34
57
|
|
35
58
|
# Sets the default week start
|
36
59
|
# If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised.
|
37
60
|
initializer "active_support.initialize_beginning_of_week" do |app|
|
38
|
-
require
|
61
|
+
require "active_support/core_ext/date/calculations"
|
39
62
|
beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week)
|
40
63
|
|
41
64
|
Date.beginning_of_week_default = beginning_of_week_default
|
42
65
|
end
|
43
66
|
|
67
|
+
initializer "active_support.require_master_key" do |app|
|
68
|
+
if app.config.respond_to?(:require_master_key) && app.config.require_master_key
|
69
|
+
begin
|
70
|
+
app.credentials.key
|
71
|
+
rescue ActiveSupport::EncryptedFile::MissingKeyError => error
|
72
|
+
$stderr.puts error.message
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
44
78
|
initializer "active_support.set_configs" do |app|
|
45
79
|
app.config.active_support.each do |k, v|
|
46
80
|
k = "#{k}="
|
47
|
-
ActiveSupport.
|
81
|
+
ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
initializer "active_support.set_hash_digest_class" do |app|
|
86
|
+
config.after_initialize do
|
87
|
+
if app.config.active_support.use_sha1_digests
|
88
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
89
|
+
config.active_support.use_sha1_digests is deprecated and will
|
90
|
+
be removed from Rails 6.2. Use
|
91
|
+
config.active_support.hash_digest_class = ::Digest::SHA1 instead.
|
92
|
+
MSG
|
93
|
+
ActiveSupport::Digest.hash_digest_class = ::Digest::SHA1
|
94
|
+
end
|
95
|
+
|
96
|
+
if klass = app.config.active_support.hash_digest_class
|
97
|
+
ActiveSupport::Digest.hash_digest_class = klass
|
98
|
+
end
|
48
99
|
end
|
49
100
|
end
|
50
101
|
end
|
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/execution_wrapper"
|
4
|
+
require "active_support/executor"
|
2
5
|
|
3
6
|
module ActiveSupport
|
4
7
|
#--
|
@@ -26,14 +29,17 @@ module ActiveSupport
|
|
26
29
|
|
27
30
|
define_callbacks :class_unload
|
28
31
|
|
32
|
+
# Registers a callback that will run once at application startup and every time the code is reloaded.
|
29
33
|
def self.to_prepare(*args, &block)
|
30
34
|
set_callback(:prepare, *args, &block)
|
31
35
|
end
|
32
36
|
|
37
|
+
# Registers a callback that will run immediately before the classes are unloaded.
|
33
38
|
def self.before_class_unload(*args, &block)
|
34
39
|
set_callback(:class_unload, *args, &block)
|
35
40
|
end
|
36
41
|
|
42
|
+
# Registers a callback that will run immediately after the classes are unloaded.
|
37
43
|
def self.after_class_unload(*args, &block)
|
38
44
|
set_callback(:class_unload, :after, *args, &block)
|
39
45
|
end
|
@@ -44,11 +50,9 @@ module ActiveSupport
|
|
44
50
|
def self.reload!
|
45
51
|
executor.wrap do
|
46
52
|
new.tap do |instance|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
instance.complete!
|
51
|
-
end
|
53
|
+
instance.run!
|
54
|
+
ensure
|
55
|
+
instance.complete!
|
52
56
|
end
|
53
57
|
end
|
54
58
|
prepare!
|
@@ -69,11 +73,8 @@ module ActiveSupport
|
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|
72
|
-
class_attribute :executor
|
73
|
-
class_attribute :check
|
74
|
-
|
75
|
-
self.executor = Executor
|
76
|
-
self.check = lambda { false }
|
76
|
+
class_attribute :executor, default: Executor
|
77
|
+
class_attribute :check, default: lambda { false }
|
77
78
|
|
78
79
|
def self.check! # :nodoc:
|
79
80
|
@should_reload ||= check.call
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
require "active_support/core_ext/class/attribute"
|
5
|
+
require "active_support/core_ext/string/inflections"
|
4
6
|
|
5
7
|
module ActiveSupport
|
6
8
|
# Rescuable module adds support for easier exception handling.
|
@@ -8,8 +10,7 @@ module ActiveSupport
|
|
8
10
|
extend Concern
|
9
11
|
|
10
12
|
included do
|
11
|
-
class_attribute :rescue_handlers
|
12
|
-
self.rescue_handlers = []
|
13
|
+
class_attribute :rescue_handlers, default: []
|
13
14
|
end
|
14
15
|
|
15
16
|
module ClassMethods
|
@@ -36,7 +37,7 @@ module ActiveSupport
|
|
36
37
|
# render xml: exception, status: 500
|
37
38
|
# end
|
38
39
|
#
|
39
|
-
#
|
40
|
+
# private
|
40
41
|
# def deny_access
|
41
42
|
# ...
|
42
43
|
# end
|
@@ -52,7 +53,7 @@ module ActiveSupport
|
|
52
53
|
if block_given?
|
53
54
|
with = block
|
54
55
|
else
|
55
|
-
raise ArgumentError,
|
56
|
+
raise ArgumentError, "Need a handler. Pass the with: keyword argument or provide a block."
|
56
57
|
end
|
57
58
|
end
|
58
59
|
|
@@ -74,7 +75,7 @@ module ActiveSupport
|
|
74
75
|
#
|
75
76
|
# If no handler matches the exception, check for a handler matching the
|
76
77
|
# (optional) exception.cause. If no handler matches the exception or its
|
77
|
-
# cause, this returns nil so you can deal with unhandled exceptions.
|
78
|
+
# cause, this returns +nil+, so you can deal with unhandled exceptions.
|
78
79
|
# Be sure to re-raise unhandled exceptions if this is what you expect.
|
79
80
|
#
|
80
81
|
# begin
|
@@ -83,11 +84,19 @@ module ActiveSupport
|
|
83
84
|
# rescue_with_handler(exception) || raise
|
84
85
|
# end
|
85
86
|
#
|
86
|
-
# Returns the exception if it was handled and nil if it was not.
|
87
|
-
def rescue_with_handler(exception, object: self)
|
87
|
+
# Returns the exception if it was handled and +nil+ if it was not.
|
88
|
+
def rescue_with_handler(exception, object: self, visited_exceptions: [])
|
89
|
+
visited_exceptions << exception
|
90
|
+
|
88
91
|
if handler = handler_for_rescue(exception, object: object)
|
89
92
|
handler.call exception
|
90
93
|
exception
|
94
|
+
elsif exception
|
95
|
+
if visited_exceptions.include?(exception.cause)
|
96
|
+
nil
|
97
|
+
else
|
98
|
+
rescue_with_handler(exception.cause, object: object, visited_exceptions: visited_exceptions)
|
99
|
+
end
|
91
100
|
end
|
92
101
|
end
|
93
102
|
|
@@ -121,7 +130,7 @@ module ActiveSupport
|
|
121
130
|
end
|
122
131
|
end
|
123
132
|
|
124
|
-
handler
|
133
|
+
handler
|
125
134
|
end
|
126
135
|
end
|
127
136
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/security_utils"
|
4
|
+
require "active_support/messages/rotator"
|
5
|
+
|
6
|
+
module ActiveSupport
|
7
|
+
# The ActiveSupport::SecureCompareRotator is a wrapper around +ActiveSupport::SecurityUtils.secure_compare+
|
8
|
+
# and allows you to rotate a previously defined value to a new one.
|
9
|
+
#
|
10
|
+
# It can be used as follow:
|
11
|
+
#
|
12
|
+
# rotator = ActiveSupport::SecureCompareRotator.new('new_production_value')
|
13
|
+
# rotator.rotate('previous_production_value')
|
14
|
+
# rotator.secure_compare!('previous_production_value')
|
15
|
+
#
|
16
|
+
# One real use case example would be to rotate a basic auth credentials:
|
17
|
+
#
|
18
|
+
# class MyController < ApplicationController
|
19
|
+
# def authenticate_request
|
20
|
+
# rotator = ActiveSupport::SecureComparerotator.new('new_password')
|
21
|
+
# rotator.rotate('old_password')
|
22
|
+
#
|
23
|
+
# authenticate_or_request_with_http_basic do |username, password|
|
24
|
+
# rotator.secure_compare!(password)
|
25
|
+
# rescue ActiveSupport::SecureCompareRotator::InvalidMatch
|
26
|
+
# false
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
class SecureCompareRotator
|
31
|
+
include SecurityUtils
|
32
|
+
prepend Messages::Rotator
|
33
|
+
|
34
|
+
InvalidMatch = Class.new(StandardError)
|
35
|
+
|
36
|
+
def initialize(value, **_options)
|
37
|
+
@value = value
|
38
|
+
end
|
39
|
+
|
40
|
+
def secure_compare!(other_value, on_rotation: @on_rotation)
|
41
|
+
secure_compare(@value, other_value) ||
|
42
|
+
run_rotations(on_rotation) { |wrapper| wrapper.secure_compare!(other_value) } ||
|
43
|
+
raise(InvalidMatch)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
def build_rotation(previous_value, _options)
|
48
|
+
self.class.new(previous_value)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -1,27 +1,38 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActiveSupport
|
4
4
|
module SecurityUtils
|
5
|
-
# Constant time string comparison.
|
5
|
+
# Constant time string comparison, for fixed length strings.
|
6
6
|
#
|
7
7
|
# The values compared should be of fixed length, such as strings
|
8
|
-
# that have already been processed by HMAC.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
# that have already been processed by HMAC. Raises in case of length mismatch.
|
9
|
+
|
10
|
+
if defined?(OpenSSL.fixed_length_secure_compare)
|
11
|
+
def fixed_length_secure_compare(a, b)
|
12
|
+
OpenSSL.fixed_length_secure_compare(a, b)
|
13
|
+
end
|
14
|
+
else
|
15
|
+
def fixed_length_secure_compare(a, b)
|
16
|
+
raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize
|
13
17
|
|
14
|
-
|
18
|
+
l = a.unpack "C#{a.bytesize}"
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
|
20
|
+
res = 0
|
21
|
+
b.each_byte { |byte| res |= byte ^ l.shift }
|
22
|
+
res == 0
|
23
|
+
end
|
19
24
|
end
|
20
|
-
module_function :
|
25
|
+
module_function :fixed_length_secure_compare
|
21
26
|
|
22
|
-
|
23
|
-
|
27
|
+
# Secure string comparison for strings of variable length.
|
28
|
+
#
|
29
|
+
# While a timing attack would not be able to discern the content of
|
30
|
+
# a secret compared via secure_compare, it is possible to determine
|
31
|
+
# the secret length. This should be considered when using secure_compare
|
32
|
+
# to compare weak, short secrets to user input.
|
33
|
+
def secure_compare(a, b)
|
34
|
+
a.length == b.length && fixed_length_secure_compare(a, b)
|
24
35
|
end
|
25
|
-
module_function :
|
36
|
+
module_function :secure_compare
|
26
37
|
end
|
27
38
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/symbol/starts_ends_with"
|
4
|
+
|
1
5
|
module ActiveSupport
|
2
6
|
# Wrapping a string in this class gives you a prettier way to test
|
3
7
|
# for equality. The value returned by <tt>Rails.env</tt> is wrapped
|
@@ -8,15 +12,20 @@ module ActiveSupport
|
|
8
12
|
# you can call this:
|
9
13
|
#
|
10
14
|
# Rails.env.production?
|
15
|
+
#
|
16
|
+
# == Instantiating a new StringInquirer
|
17
|
+
#
|
18
|
+
# vehicle = ActiveSupport::StringInquirer.new('car')
|
19
|
+
# vehicle.car? # => true
|
20
|
+
# vehicle.bike? # => false
|
11
21
|
class StringInquirer < String
|
12
22
|
private
|
13
|
-
|
14
23
|
def respond_to_missing?(method_name, include_private = false)
|
15
|
-
method_name
|
24
|
+
method_name.end_with?("?") || super
|
16
25
|
end
|
17
26
|
|
18
27
|
def method_missing(method_name, *arguments)
|
19
|
-
if method_name
|
28
|
+
if method_name.end_with?("?")
|
20
29
|
self == method_name[0..-2]
|
21
30
|
else
|
22
31
|
super
|