activesupport 4.1.15 → 4.2.11.3
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 +395 -574
- data/README.rdoc +7 -2
- data/lib/active_support.rb +19 -0
- data/lib/active_support/backtrace_cleaner.rb +4 -4
- data/lib/active_support/cache.rb +17 -19
- data/lib/active_support/cache/file_store.rb +5 -0
- data/lib/active_support/cache/mem_cache_store.rb +1 -1
- data/lib/active_support/cache/strategy/local_cache.rb +5 -4
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +5 -0
- data/lib/active_support/callbacks.rb +41 -33
- data/lib/active_support/concern.rb +10 -2
- data/lib/active_support/core_ext/array/access.rb +9 -1
- data/lib/active_support/core_ext/array/grouping.rb +5 -0
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +2 -0
- data/lib/active_support/core_ext/class/delegating_attributes.rb +4 -0
- data/lib/active_support/core_ext/class/subclasses.rb +0 -2
- data/lib/active_support/core_ext/date/conversions.rb +6 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +11 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/date_time.rb +1 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +34 -4
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +16 -0
- data/lib/active_support/core_ext/file/atomic.rb +1 -1
- data/lib/active_support/core_ext/hash.rb +1 -0
- data/lib/active_support/core_ext/hash/compact.rb +20 -16
- data/lib/active_support/core_ext/hash/conversions.rb +3 -5
- data/lib/active_support/core_ext/hash/except.rb +8 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +10 -6
- data/lib/active_support/core_ext/hash/slice.rb +8 -2
- data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
- data/lib/active_support/core_ext/integer/time.rb +0 -15
- data/lib/active_support/core_ext/kernel.rb +3 -2
- data/lib/active_support/core_ext/kernel/concern.rb +10 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +1 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +15 -0
- data/lib/active_support/core_ext/load_error.rb +4 -1
- data/lib/active_support/core_ext/marshal.rb +8 -5
- data/lib/active_support/core_ext/module/aliasing.rb +2 -2
- data/lib/active_support/core_ext/module/delegation.rb +34 -18
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -1
- data/lib/active_support/core_ext/numeric/conversions.rb +11 -3
- data/lib/active_support/core_ext/numeric/time.rb +1 -34
- data/lib/active_support/core_ext/object.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +2 -2
- data/lib/active_support/core_ext/object/duplicable.rb +62 -33
- data/lib/active_support/core_ext/object/itself.rb +15 -0
- data/lib/active_support/core_ext/object/json.rb +2 -2
- data/lib/active_support/core_ext/object/to_query.rb +2 -1
- data/lib/active_support/core_ext/object/try.rb +35 -13
- data/lib/active_support/core_ext/object/with_options.rb +30 -3
- data/lib/active_support/core_ext/string/access.rb +5 -5
- data/lib/active_support/core_ext/string/conversions.rb +1 -1
- data/lib/active_support/core_ext/string/filters.rb +44 -6
- data/lib/active_support/core_ext/string/inflections.rb +4 -1
- data/lib/active_support/core_ext/string/output_safety.rb +33 -14
- data/lib/active_support/core_ext/thread.rb +7 -0
- data/lib/active_support/core_ext/time.rb +1 -0
- data/lib/active_support/core_ext/time/calculations.rb +31 -7
- data/lib/active_support/core_ext/time/compatibility.rb +14 -0
- data/lib/active_support/core_ext/time/conversions.rb +1 -1
- data/lib/active_support/dependencies.rb +32 -18
- data/lib/active_support/dependencies/autoload.rb +1 -1
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/deprecation/behaviors.rb +1 -1
- data/lib/active_support/duration.rb +47 -5
- data/lib/active_support/gem_version.rb +4 -4
- data/lib/active_support/hash_with_indifferent_access.rb +35 -7
- data/lib/active_support/i18n_railtie.rb +1 -7
- data/lib/active_support/inflector/inflections.rb +2 -2
- data/lib/active_support/inflector/methods.rb +43 -19
- data/lib/active_support/json/decoding.rb +1 -1
- data/lib/active_support/json/encoding.rb +3 -2
- data/lib/active_support/logger.rb +36 -0
- data/lib/active_support/logger_silence.rb +4 -22
- data/lib/active_support/logger_thread_safe_level.rb +32 -0
- data/lib/active_support/message_encryptor.rb +10 -2
- data/lib/active_support/message_verifier.rb +11 -12
- data/lib/active_support/multibyte/chars.rb +1 -1
- data/lib/active_support/multibyte/unicode.rb +5 -4
- data/lib/active_support/notifications.rb +8 -3
- data/lib/active_support/notifications/fanout.rb +12 -7
- data/lib/active_support/number_helper.rb +12 -13
- data/lib/active_support/number_helper/number_to_currency_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +1 -1
- data/lib/active_support/per_thread_registry.rb +5 -3
- data/lib/active_support/test_case.rb +46 -12
- data/lib/active_support/testing/assertions.rb +1 -1
- data/lib/active_support/testing/constant_lookup.rb +1 -5
- data/lib/active_support/testing/declarative.rb +1 -25
- data/lib/active_support/testing/isolation.rb +16 -6
- data/lib/active_support/testing/tagged_logging.rb +1 -1
- data/lib/active_support/testing/time_helpers.rb +23 -16
- data/lib/active_support/time.rb +0 -2
- data/lib/active_support/time_with_zone.rb +48 -29
- data/lib/active_support/values/time_zone.rb +81 -75
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini.rb +30 -15
- data/lib/active_support/xml_mini/libxml.rb +1 -3
- data/lib/active_support/xml_mini/libxmlsax.rb +1 -4
- data/lib/active_support/xml_mini/nokogiri.rb +1 -3
- data/lib/active_support/xml_mini/nokogirisax.rb +1 -3
- data/lib/active_support/xml_mini/rexml.rb +1 -3
- metadata +21 -36
- data/lib/active_support/core_ext/object/to_json.rb +0 -5
- data/lib/active_support/file_watcher.rb +0 -36
@@ -1,14 +1,14 @@
|
|
1
1
|
module ActiveSupport
|
2
|
-
# Returns the version of the currently loaded
|
2
|
+
# Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>
|
3
3
|
def self.gem_version
|
4
4
|
Gem::Version.new VERSION::STRING
|
5
5
|
end
|
6
6
|
|
7
7
|
module VERSION
|
8
8
|
MAJOR = 4
|
9
|
-
MINOR =
|
10
|
-
TINY =
|
11
|
-
PRE =
|
9
|
+
MINOR = 2
|
10
|
+
TINY = 11
|
11
|
+
PRE = "3"
|
12
12
|
|
13
13
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
14
14
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_support/core_ext/hash/keys'
|
2
|
+
require 'active_support/core_ext/hash/reverse_merge'
|
2
3
|
|
3
4
|
module ActiveSupport
|
4
5
|
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
@@ -55,7 +56,7 @@ module ActiveSupport
|
|
55
56
|
end
|
56
57
|
|
57
58
|
def initialize(constructor = {})
|
58
|
-
if constructor.
|
59
|
+
if constructor.respond_to?(:to_hash)
|
59
60
|
super()
|
60
61
|
update(constructor)
|
61
62
|
else
|
@@ -75,6 +76,7 @@ module ActiveSupport
|
|
75
76
|
hash = hash.to_hash
|
76
77
|
new(hash).tap do |new_hash|
|
77
78
|
new_hash.default = hash.default
|
79
|
+
new_hash.default_proc = hash.default_proc if hash.default_proc
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
@@ -176,10 +178,17 @@ module ActiveSupport
|
|
176
178
|
indices.collect { |key| self[convert_key(key)] }
|
177
179
|
end
|
178
180
|
|
179
|
-
# Returns
|
181
|
+
# Returns a shallow copy of the hash.
|
182
|
+
#
|
183
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
184
|
+
# dup = hash.dup
|
185
|
+
# dup[:a][:c] = 'c'
|
186
|
+
#
|
187
|
+
# hash[:a][:c] # => nil
|
188
|
+
# dup[:a][:c] # => "c"
|
180
189
|
def dup
|
181
190
|
self.class.new(self).tap do |new_hash|
|
182
|
-
new_hash
|
191
|
+
set_defaults(new_hash)
|
183
192
|
end
|
184
193
|
end
|
185
194
|
|
@@ -236,13 +245,24 @@ module ActiveSupport
|
|
236
245
|
dup.tap { |hash| hash.reject!(*args, &block) }
|
237
246
|
end
|
238
247
|
|
248
|
+
def transform_values(*args, &block)
|
249
|
+
return to_enum(:transform_values) unless block_given?
|
250
|
+
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
251
|
+
end
|
252
|
+
|
253
|
+
def compact
|
254
|
+
dup.tap(&:compact!)
|
255
|
+
end
|
256
|
+
|
239
257
|
# Convert to a regular hash with string keys.
|
240
258
|
def to_hash
|
241
|
-
_new_hash=
|
259
|
+
_new_hash = Hash.new
|
260
|
+
set_defaults(_new_hash)
|
261
|
+
|
242
262
|
each do |key, value|
|
243
|
-
_new_hash[
|
263
|
+
_new_hash[key] = convert_value(value, for: :to_hash)
|
244
264
|
end
|
245
|
-
|
265
|
+
_new_hash
|
246
266
|
end
|
247
267
|
|
248
268
|
protected
|
@@ -258,7 +278,7 @@ module ActiveSupport
|
|
258
278
|
value.nested_under_indifferent_access
|
259
279
|
end
|
260
280
|
elsif value.is_a?(Array)
|
261
|
-
|
281
|
+
if options[:for] != :assignment || value.frozen?
|
262
282
|
value = value.dup
|
263
283
|
end
|
264
284
|
value.map! { |e| convert_value(e, options) }
|
@@ -266,6 +286,14 @@ module ActiveSupport
|
|
266
286
|
value
|
267
287
|
end
|
268
288
|
end
|
289
|
+
|
290
|
+
def set_defaults(target)
|
291
|
+
if default_proc
|
292
|
+
target.default_proc = default_proc.dup
|
293
|
+
else
|
294
|
+
target.default = default
|
295
|
+
end
|
296
|
+
end
|
269
297
|
end
|
270
298
|
end
|
271
299
|
|
@@ -8,8 +8,6 @@ module I18n
|
|
8
8
|
config.i18n.railties_load_path = []
|
9
9
|
config.i18n.load_path = []
|
10
10
|
config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
|
11
|
-
# Enforce I18n to check the available locales when setting a locale.
|
12
|
-
config.i18n.enforce_available_locales = true
|
13
11
|
|
14
12
|
# Set the i18n configuration after initialization since a lot of
|
15
13
|
# configuration is still usually done in application initializers.
|
@@ -36,11 +34,7 @@ module I18n
|
|
36
34
|
# Avoid issues with setting the default_locale by disabling available locales
|
37
35
|
# check while configuring.
|
38
36
|
enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
|
39
|
-
|
40
|
-
if enforce_available_locales.nil?
|
41
|
-
enforce_available_locales = I18n.enforce_available_locales
|
42
|
-
end
|
43
|
-
|
37
|
+
enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
|
44
38
|
I18n.enforce_available_locales = false
|
45
39
|
|
46
40
|
app.config.i18n.each do |setting, value|
|
@@ -154,13 +154,13 @@ module ActiveSupport
|
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
157
|
-
#
|
157
|
+
# Specifies words that are uncountable and should not be inflected.
|
158
158
|
#
|
159
159
|
# uncountable 'money'
|
160
160
|
# uncountable 'money', 'information'
|
161
161
|
# uncountable %w( money information rice )
|
162
162
|
def uncountable(*words)
|
163
|
-
|
163
|
+
@uncountables += words.flatten.map(&:downcase)
|
164
164
|
end
|
165
165
|
|
166
166
|
# Specifies a humanized form of a string by a regular expression rule or
|
@@ -73,7 +73,7 @@ module ActiveSupport
|
|
73
73
|
string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
74
74
|
end
|
75
75
|
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }
|
76
|
-
string.gsub!(
|
76
|
+
string.gsub!(/\//, '::')
|
77
77
|
string
|
78
78
|
end
|
79
79
|
|
@@ -89,8 +89,9 @@ module ActiveSupport
|
|
89
89
|
#
|
90
90
|
# 'SSLError'.underscore.camelize # => "SslError"
|
91
91
|
def underscore(camel_cased_word)
|
92
|
-
|
93
|
-
word.gsub
|
92
|
+
return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
|
93
|
+
word = camel_cased_word.to_s.gsub(/::/, '/')
|
94
|
+
word.gsub!(/(?:(?<=([A-Za-z\d]))|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1 && '_'}#{$2.downcase}" }
|
94
95
|
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
95
96
|
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
96
97
|
word.tr!("-", "_")
|
@@ -98,26 +99,46 @@ module ActiveSupport
|
|
98
99
|
word
|
99
100
|
end
|
100
101
|
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
102
|
+
# Tweaks an attribute name for display to end users.
|
103
|
+
#
|
104
|
+
# Specifically, +humanize+ performs these transformations:
|
105
|
+
#
|
106
|
+
# * Applies human inflection rules to the argument.
|
107
|
+
# * Deletes leading underscores, if any.
|
108
|
+
# * Removes a "_id" suffix if present.
|
109
|
+
# * Replaces underscores with spaces, if any.
|
110
|
+
# * Downcases all words except acronyms.
|
111
|
+
# * Capitalizes the first word.
|
104
112
|
#
|
105
113
|
# The capitalization of the first word can be turned off by setting the
|
106
|
-
#
|
107
|
-
# By default, this parameter is true.
|
114
|
+
# +:capitalize+ option to false (default is true).
|
108
115
|
#
|
109
116
|
# humanize('employee_salary') # => "Employee salary"
|
110
117
|
# humanize('author_id') # => "Author"
|
111
118
|
# humanize('author_id', capitalize: false) # => "author"
|
119
|
+
# humanize('_id') # => "Id"
|
120
|
+
#
|
121
|
+
# If "SSL" was defined to be an acronym:
|
122
|
+
#
|
123
|
+
# humanize('ssl_error') # => "SSL error"
|
124
|
+
#
|
112
125
|
def humanize(lower_case_and_underscored_word, options = {})
|
113
126
|
result = lower_case_and_underscored_word.to_s.dup
|
127
|
+
|
114
128
|
inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) }
|
115
|
-
|
129
|
+
|
130
|
+
result.sub!(/\A_+/, '')
|
131
|
+
result.sub!(/_id\z/, '')
|
116
132
|
result.tr!('_', ' ')
|
117
|
-
|
133
|
+
|
134
|
+
result.gsub!(/([a-z\d]*)/i) do |match|
|
118
135
|
"#{inflections.acronyms[match] || match.downcase}"
|
119
|
-
|
120
|
-
|
136
|
+
end
|
137
|
+
|
138
|
+
if options.fetch(:capitalize, true)
|
139
|
+
result.sub!(/\A\w/) { |match| match.upcase }
|
140
|
+
end
|
141
|
+
|
121
142
|
result
|
122
143
|
end
|
123
144
|
|
@@ -132,7 +153,7 @@ module ActiveSupport
|
|
132
153
|
# 'TheManWithoutAPast'.titleize # => "The Man Without A Past"
|
133
154
|
# 'raiders_of_the_lost_ark'.titleize # => "Raiders Of The Lost Ark"
|
134
155
|
def titleize(word)
|
135
|
-
humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) {
|
156
|
+
humanize(underscore(word)).gsub(/\b(?<!['’`])[a-z]/) { |match| match.capitalize }
|
136
157
|
end
|
137
158
|
|
138
159
|
# Create the name of a table like Rails does for models to table names. This
|
@@ -171,6 +192,8 @@ module ActiveSupport
|
|
171
192
|
#
|
172
193
|
# 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
|
173
194
|
# 'Inflections'.demodulize # => "Inflections"
|
195
|
+
# '::Inflections'.demodulize # => "Inflections"
|
196
|
+
# ''.demodulize # => ""
|
174
197
|
#
|
175
198
|
# See also +deconstantize+.
|
176
199
|
def demodulize(path)
|
@@ -227,7 +250,7 @@ module ActiveSupport
|
|
227
250
|
def constantize(camel_cased_word)
|
228
251
|
names = camel_cased_word.split('::')
|
229
252
|
|
230
|
-
# Trigger a
|
253
|
+
# Trigger a built-in NameError exception including the ill-formed constant in the message.
|
231
254
|
Object.const_get(camel_cased_word) if names.empty?
|
232
255
|
|
233
256
|
# Remove the first blank element in case of '::ClassName' notation.
|
@@ -241,8 +264,8 @@ module ActiveSupport
|
|
241
264
|
next candidate if constant.const_defined?(name, false)
|
242
265
|
next candidate unless Object.const_defined?(name)
|
243
266
|
|
244
|
-
# Go down the ancestors to check
|
245
|
-
#
|
267
|
+
# Go down the ancestors to check if it is owned directly. The check
|
268
|
+
# stops when we reach Object or the end of ancestors tree.
|
246
269
|
constant = constant.ancestors.inject do |const, ancestor|
|
247
270
|
break const if ancestor == Object
|
248
271
|
break ancestor if ancestor.const_defined?(name, false)
|
@@ -325,10 +348,11 @@ module ActiveSupport
|
|
325
348
|
|
326
349
|
private
|
327
350
|
|
328
|
-
#
|
351
|
+
# Mounts a regular expression, returned as a string to ease interpolation,
|
352
|
+
# that will match part by part the given constant.
|
329
353
|
#
|
330
|
-
# const_regexp("Foo::Bar::Baz") # =>
|
331
|
-
# const_regexp("::") # =>
|
354
|
+
# const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?"
|
355
|
+
# const_regexp("::") # => "::"
|
332
356
|
def const_regexp(camel_cased_word) #:nodoc:
|
333
357
|
parts = camel_cased_word.split("::")
|
334
358
|
|
@@ -12,7 +12,7 @@ module ActiveSupport
|
|
12
12
|
|
13
13
|
class << self
|
14
14
|
# Parses a JSON string (JavaScript Object Notation) into a hash.
|
15
|
-
# See www.json.org for more info.
|
15
|
+
# See http://www.json.org for more info.
|
16
16
|
#
|
17
17
|
# ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}")
|
18
18
|
# => {"team" => "rails", "players" => "36"}
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_support/core_ext/object/json'
|
2
2
|
require 'active_support/core_ext/module/delegation'
|
3
|
+
require 'active_support/deprecation'
|
3
4
|
|
4
5
|
module ActiveSupport
|
5
6
|
class << self
|
@@ -13,7 +14,7 @@ module ActiveSupport
|
|
13
14
|
|
14
15
|
module JSON
|
15
16
|
# Dumps objects in JSON (JavaScript Object Notation).
|
16
|
-
# See www.json.org for more info.
|
17
|
+
# See http://www.json.org for more info.
|
17
18
|
#
|
18
19
|
# ActiveSupport::JSON.encode({ team: 'rails', players: '36' })
|
19
20
|
# # => "{\"team\":\"rails\",\"players\":\"36\"}"
|
@@ -135,7 +136,7 @@ module ActiveSupport
|
|
135
136
|
"The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \
|
136
137
|
"the new encoder will always encode them as strings.\n\n" \
|
137
138
|
"You are seeing this error because you are trying to check the value of the related configuration, " \
|
138
|
-
"
|
139
|
+
"`active_support.encode_big_decimal_as_string`. If your application depends on this option, you should " \
|
139
140
|
"add the 'activesupport-json_encoder' gem to your Gemfile. For now, this option will always be true. " \
|
140
141
|
"In the future, it will be removed from Rails, so you should stop checking its value."
|
141
142
|
|
@@ -1,11 +1,24 @@
|
|
1
1
|
require 'active_support/core_ext/module/attribute_accessors'
|
2
2
|
require 'active_support/logger_silence'
|
3
|
+
require 'active_support/logger_thread_safe_level'
|
3
4
|
require 'logger'
|
4
5
|
|
5
6
|
module ActiveSupport
|
6
7
|
class Logger < ::Logger
|
8
|
+
include ActiveSupport::LoggerThreadSafeLevel
|
7
9
|
include LoggerSilence
|
8
10
|
|
11
|
+
# Returns true if the logger destination matches one of the sources
|
12
|
+
#
|
13
|
+
# logger = Logger.new(STDOUT)
|
14
|
+
# ActiveSupport::Logger.logger_outputs_to?(logger, STDOUT)
|
15
|
+
# # => true
|
16
|
+
def self.logger_outputs_to?(logger, *sources)
|
17
|
+
logdev = logger.instance_variable_get("@logdev")
|
18
|
+
logger_source = logdev.dev if logdev.respond_to?(:dev)
|
19
|
+
sources.any? { |source| source == logger_source }
|
20
|
+
end
|
21
|
+
|
9
22
|
# Broadcasts logs to multiple loggers.
|
10
23
|
def self.broadcast(logger) # :nodoc:
|
11
24
|
Module.new do
|
@@ -38,6 +51,29 @@ module ActiveSupport
|
|
38
51
|
logger.level = level
|
39
52
|
super(level)
|
40
53
|
end
|
54
|
+
|
55
|
+
define_method(:local_level=) do |level|
|
56
|
+
logger.local_level = level if logger.respond_to?(:local_level=)
|
57
|
+
super(level) if respond_to?(:local_level=)
|
58
|
+
end
|
59
|
+
|
60
|
+
define_method(:silence) do |level = Logger::ERROR, &block|
|
61
|
+
if logger.respond_to?(:silence) && logger.method(:silence).owner != ::Kernel
|
62
|
+
logger.silence(level) do
|
63
|
+
if respond_to?(:silence) && method(:silence).owner != ::Kernel
|
64
|
+
super(level, &block)
|
65
|
+
else
|
66
|
+
block.call(self)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else
|
70
|
+
if respond_to?(:silence) && method(:silence).owner != ::Kernel
|
71
|
+
super(level, &block)
|
72
|
+
else
|
73
|
+
block.call(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
41
77
|
end
|
42
78
|
end
|
43
79
|
|
@@ -3,40 +3,22 @@ require 'thread_safe'
|
|
3
3
|
|
4
4
|
module LoggerSilence
|
5
5
|
extend ActiveSupport::Concern
|
6
|
-
|
6
|
+
|
7
7
|
included do
|
8
8
|
cattr_accessor :silencer
|
9
|
-
attr_reader :local_levels
|
10
9
|
self.silencer = true
|
11
10
|
end
|
12
11
|
|
13
|
-
|
14
|
-
def after_initialize
|
15
|
-
@local_levels = ThreadSafe::Cache.new(:initial_capacity => 2)
|
16
|
-
end
|
17
|
-
|
18
|
-
def local_log_id
|
19
|
-
Thread.current.__id__
|
20
|
-
end
|
21
|
-
|
22
|
-
def level
|
23
|
-
local_levels[local_log_id] || super
|
24
|
-
end
|
25
|
-
|
26
12
|
# Silences the logger for the duration of the block.
|
27
13
|
def silence(temporary_level = Logger::ERROR)
|
28
14
|
if silencer
|
29
15
|
begin
|
30
|
-
old_local_level =
|
31
|
-
|
16
|
+
old_local_level = local_level
|
17
|
+
self.local_level = temporary_level
|
32
18
|
|
33
19
|
yield self
|
34
20
|
ensure
|
35
|
-
|
36
|
-
local_levels[local_log_id] = old_local_level
|
37
|
-
else
|
38
|
-
local_levels.delete(local_log_id)
|
39
|
-
end
|
21
|
+
self.local_level = old_local_level
|
40
22
|
end
|
41
23
|
else
|
42
24
|
yield self
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'thread_safe'
|
3
|
+
|
4
|
+
module ActiveSupport
|
5
|
+
module LoggerThreadSafeLevel
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
def after_initialize
|
9
|
+
@local_levels = ThreadSafe::Cache.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def local_log_id
|
13
|
+
Thread.current.__id__
|
14
|
+
end
|
15
|
+
|
16
|
+
def local_level
|
17
|
+
@local_levels[local_log_id]
|
18
|
+
end
|
19
|
+
|
20
|
+
def local_level=(level)
|
21
|
+
if level
|
22
|
+
@local_levels[local_log_id] = level
|
23
|
+
else
|
24
|
+
@local_levels.delete(local_log_id)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def level
|
29
|
+
local_level || super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -18,6 +18,8 @@ module ActiveSupport
|
|
18
18
|
# encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..."
|
19
19
|
# crypt.decrypt_and_verify(encrypted_data) # => "my secret data"
|
20
20
|
class MessageEncryptor
|
21
|
+
DEFAULT_CIPHER = "aes-256-cbc"
|
22
|
+
|
21
23
|
module NullSerializer #:nodoc:
|
22
24
|
def self.load(value)
|
23
25
|
value
|
@@ -40,6 +42,7 @@ module ActiveSupport
|
|
40
42
|
# Options:
|
41
43
|
# * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by
|
42
44
|
# <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'.
|
45
|
+
# * <tt>:digest</tt> - String of digest to use for signing. Default is +SHA1+.
|
43
46
|
# * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+.
|
44
47
|
def initialize(secret, *signature_key_or_options)
|
45
48
|
options = signature_key_or_options.extract_options!
|
@@ -47,7 +50,7 @@ module ActiveSupport
|
|
47
50
|
@secret = secret
|
48
51
|
@sign_secret = sign_secret
|
49
52
|
@cipher = options[:cipher] || 'aes-256-cbc'
|
50
|
-
@verifier = MessageVerifier.new(@sign_secret || @secret, :serializer
|
53
|
+
@verifier = MessageVerifier.new(@sign_secret || @secret, digest: options[:digest] || 'SHA1', serializer: NullSerializer)
|
51
54
|
@serializer = options[:serializer] || Marshal
|
52
55
|
end
|
53
56
|
|
@@ -63,6 +66,11 @@ module ActiveSupport
|
|
63
66
|
_decrypt(verifier.verify(value))
|
64
67
|
end
|
65
68
|
|
69
|
+
# Given a cipher, returns the key length of the cipher to help generate the key of desired size
|
70
|
+
def self.key_len(cipher = DEFAULT_CIPHER)
|
71
|
+
OpenSSL::Cipher.new(cipher).key_len
|
72
|
+
end
|
73
|
+
|
66
74
|
private
|
67
75
|
|
68
76
|
def _encrypt(value)
|
@@ -96,7 +104,7 @@ module ActiveSupport
|
|
96
104
|
end
|
97
105
|
|
98
106
|
def new_cipher
|
99
|
-
OpenSSL::Cipher
|
107
|
+
OpenSSL::Cipher.new(@cipher)
|
100
108
|
end
|
101
109
|
|
102
110
|
def verifier
|