activesupport 4.2.11.3 → 5.0.0.beta1

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.

Files changed (174) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +309 -485
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/active_support.rb +8 -15
  6. data/lib/active_support/array_inquirer.rb +44 -0
  7. data/lib/active_support/backtrace_cleaner.rb +1 -1
  8. data/lib/active_support/cache.rb +59 -72
  9. data/lib/active_support/cache/file_store.rb +27 -19
  10. data/lib/active_support/cache/mem_cache_store.rb +71 -60
  11. data/lib/active_support/cache/memory_store.rb +16 -21
  12. data/lib/active_support/cache/null_store.rb +1 -4
  13. data/lib/active_support/cache/strategy/local_cache.rb +31 -20
  14. data/lib/active_support/callbacks.rb +107 -111
  15. data/lib/active_support/concern.rb +1 -1
  16. data/lib/active_support/concurrency/latch.rb +7 -15
  17. data/lib/active_support/concurrency/share_lock.rb +142 -0
  18. data/lib/active_support/configurable.rb +1 -0
  19. data/lib/active_support/core_ext.rb +2 -1
  20. data/lib/active_support/core_ext/array.rb +1 -0
  21. data/lib/active_support/core_ext/array/access.rb +13 -1
  22. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  23. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +5 -4
  25. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
  26. data/lib/active_support/core_ext/class.rb +0 -1
  27. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  28. data/lib/active_support/core_ext/class/subclasses.rb +5 -2
  29. data/lib/active_support/core_ext/date.rb +1 -1
  30. data/lib/active_support/core_ext/date/blank.rb +12 -0
  31. data/lib/active_support/core_ext/date/calculations.rb +1 -1
  32. data/lib/active_support/core_ext/date/conversions.rb +3 -3
  33. data/lib/active_support/core_ext/date_and_time/calculations.rb +93 -27
  34. data/lib/active_support/core_ext/date_and_time/zones.rb +1 -2
  35. data/lib/active_support/core_ext/date_time.rb +1 -1
  36. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  37. data/lib/active_support/core_ext/date_time/calculations.rb +7 -23
  38. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  39. data/lib/active_support/core_ext/enumerable.rb +27 -17
  40. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  41. data/lib/active_support/core_ext/hash/compact.rb +15 -19
  42. data/lib/active_support/core_ext/hash/conversions.rb +21 -2
  43. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
  44. data/lib/active_support/core_ext/hash/except.rb +9 -8
  45. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  46. data/lib/active_support/core_ext/hash/keys.rb +22 -18
  47. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  48. data/lib/active_support/core_ext/hash/transform_values.rb +13 -7
  49. data/lib/active_support/core_ext/integer/time.rb +1 -1
  50. data/lib/active_support/core_ext/kernel.rb +0 -1
  51. data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
  52. data/lib/active_support/core_ext/kernel/reporting.rb +0 -84
  53. data/lib/active_support/core_ext/load_error.rb +4 -2
  54. data/lib/active_support/core_ext/marshal.rb +8 -13
  55. data/lib/active_support/core_ext/module.rb +1 -0
  56. data/lib/active_support/core_ext/module/aliasing.rb +6 -1
  57. data/lib/active_support/core_ext/module/anonymous.rb +10 -1
  58. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  59. data/lib/active_support/core_ext/module/attribute_accessors.rb +7 -7
  60. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  61. data/lib/active_support/core_ext/module/concerning.rb +4 -4
  62. data/lib/active_support/core_ext/module/delegation.rb +7 -14
  63. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
  64. data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
  65. data/lib/active_support/core_ext/module/remove_method.rb +23 -0
  66. data/lib/active_support/core_ext/name_error.rb +15 -2
  67. data/lib/active_support/core_ext/numeric.rb +1 -0
  68. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  69. data/lib/active_support/core_ext/numeric/conversions.rb +12 -23
  70. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  71. data/lib/active_support/core_ext/numeric/time.rb +20 -0
  72. data/lib/active_support/core_ext/object.rb +0 -1
  73. data/lib/active_support/core_ext/object/blank.rb +11 -2
  74. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  75. data/lib/active_support/core_ext/object/duplicable.rb +39 -70
  76. data/lib/active_support/core_ext/object/inclusion.rb +2 -2
  77. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  78. data/lib/active_support/core_ext/object/json.rb +9 -7
  79. data/lib/active_support/core_ext/object/to_query.rb +1 -1
  80. data/lib/active_support/core_ext/object/try.rb +67 -21
  81. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  82. data/lib/active_support/core_ext/range/conversions.rb +18 -6
  83. data/lib/active_support/core_ext/range/each.rb +16 -18
  84. data/lib/active_support/core_ext/range/include_range.rb +20 -20
  85. data/lib/active_support/core_ext/securerandom.rb +23 -0
  86. data/lib/active_support/core_ext/string/access.rb +1 -1
  87. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  88. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  89. data/lib/active_support/core_ext/string/filters.rb +1 -2
  90. data/lib/active_support/core_ext/string/inflections.rb +23 -5
  91. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  92. data/lib/active_support/core_ext/string/output_safety.rb +8 -9
  93. data/lib/active_support/core_ext/string/strip.rb +3 -6
  94. data/lib/active_support/core_ext/struct.rb +3 -6
  95. data/lib/active_support/core_ext/time.rb +0 -2
  96. data/lib/active_support/core_ext/time/calculations.rb +18 -16
  97. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  98. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  99. data/lib/active_support/core_ext/time/zones.rb +19 -3
  100. data/lib/active_support/core_ext/uri.rb +1 -3
  101. data/lib/active_support/dependencies.rb +79 -44
  102. data/lib/active_support/dependencies/interlock.rb +47 -0
  103. data/lib/active_support/deprecation/behaviors.rb +12 -0
  104. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  105. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  106. data/lib/active_support/deprecation/reporting.rb +13 -2
  107. data/lib/active_support/duration.rb +5 -8
  108. data/lib/active_support/evented_file_update_checker.rb +150 -0
  109. data/lib/active_support/file_update_checker.rb +1 -1
  110. data/lib/active_support/gem_version.rb +5 -5
  111. data/lib/active_support/hash_with_indifferent_access.rb +15 -17
  112. data/lib/active_support/i18n_railtie.rb +25 -4
  113. data/lib/active_support/inflector/inflections.rb +36 -5
  114. data/lib/active_support/inflector/methods.rb +87 -89
  115. data/lib/active_support/inflector/transliterate.rb +36 -21
  116. data/lib/active_support/json/decoding.rb +2 -8
  117. data/lib/active_support/json/encoding.rb +0 -50
  118. data/lib/active_support/key_generator.rb +4 -4
  119. data/lib/active_support/log_subscriber.rb +1 -1
  120. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  121. data/lib/active_support/logger.rb +4 -52
  122. data/lib/active_support/logger_silence.rb +3 -5
  123. data/lib/active_support/message_encryptor.rb +4 -11
  124. data/lib/active_support/message_verifier.rb +64 -8
  125. data/lib/active_support/multibyte/chars.rb +12 -3
  126. data/lib/active_support/multibyte/unicode.rb +6 -8
  127. data/lib/active_support/notifications.rb +2 -2
  128. data/lib/active_support/notifications/fanout.rb +5 -5
  129. data/lib/active_support/notifications/instrumenter.rb +19 -2
  130. data/lib/active_support/number_helper.rb +21 -15
  131. data/lib/active_support/number_helper/number_to_currency_converter.rb +4 -4
  132. data/lib/active_support/number_helper/number_to_delimited_converter.rb +7 -2
  133. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  134. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -1
  135. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  136. data/lib/active_support/number_helper/number_to_rounded_converter.rb +28 -25
  137. data/lib/active_support/ordered_options.rb +15 -1
  138. data/lib/active_support/per_thread_registry.rb +3 -0
  139. data/lib/active_support/rails.rb +2 -2
  140. data/lib/active_support/railtie.rb +6 -1
  141. data/lib/active_support/rescuable.rb +4 -4
  142. data/lib/active_support/security_utils.rb +0 -7
  143. data/lib/active_support/string_inquirer.rb +1 -1
  144. data/lib/active_support/subscriber.rb +5 -10
  145. data/lib/active_support/tagged_logging.rb +3 -1
  146. data/lib/active_support/test_case.rb +13 -25
  147. data/lib/active_support/testing/assertions.rb +15 -13
  148. data/lib/active_support/testing/autorun.rb +8 -1
  149. data/lib/active_support/testing/composite_filter.rb +54 -0
  150. data/lib/active_support/testing/deprecation.rb +9 -8
  151. data/lib/active_support/testing/file_fixtures.rb +34 -0
  152. data/lib/active_support/testing/isolation.rb +22 -8
  153. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  154. data/lib/active_support/testing/stream.rb +42 -0
  155. data/lib/active_support/testing/time_helpers.rb +6 -6
  156. data/lib/active_support/time_with_zone.rb +135 -53
  157. data/lib/active_support/values/time_zone.rb +80 -46
  158. data/lib/active_support/values/unicode_tables.dat +0 -0
  159. data/lib/active_support/xml_mini.rb +15 -30
  160. data/lib/active_support/xml_mini/jdom.rb +1 -1
  161. data/lib/active_support/xml_mini/libxml.rb +5 -3
  162. data/lib/active_support/xml_mini/libxmlsax.rb +4 -1
  163. data/lib/active_support/xml_mini/nokogiri.rb +5 -3
  164. data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
  165. data/lib/active_support/xml_mini/rexml.rb +3 -1
  166. metadata +57 -21
  167. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  168. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  169. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -15
  170. data/lib/active_support/core_ext/date_time/compatibility.rb +0 -16
  171. data/lib/active_support/core_ext/object/itself.rb +0 -15
  172. data/lib/active_support/core_ext/thread.rb +0 -86
  173. data/lib/active_support/core_ext/time/compatibility.rb +0 -14
  174. data/lib/active_support/logger_thread_safe_level.rb +0 -32
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  require 'active_support/core_ext/string/multibyte'
3
2
  require 'active_support/i18n'
4
3
 
@@ -58,7 +57,7 @@ module ActiveSupport
58
57
  # I18n.locale = :de
59
58
  # transliterate('Jürgen')
60
59
  # # => "Juergen"
61
- def transliterate(string, replacement = "?")
60
+ def transliterate(string, replacement = "?".freeze)
62
61
  I18n.transliterate(ActiveSupport::Multibyte::Unicode.normalize(
63
62
  ActiveSupport::Multibyte::Unicode.tidy_bytes(string), :c),
64
63
  :replacement => replacement)
@@ -67,31 +66,47 @@ module ActiveSupport
67
66
  # Replaces special characters in a string so that it may be used as part of
68
67
  # a 'pretty' URL.
69
68
  #
70
- # class Person
71
- # def to_param
72
- # "#{id}-#{name.parameterize}"
73
- # end
74
- # end
69
+ # parameterize("Donald E. Knuth") # => "donald-e-knuth"
70
+ # parameterize("^trés|Jolie-- ") # => "tres-jolie"
75
71
  #
76
- # @person = Person.find(1)
77
- # # => #<Person id: 1, name: "Donald E. Knuth">
72
+ # To use a custom separator, override the `separator` argument.
78
73
  #
79
- # <%= link_to(@person.name, person_path(@person)) %>
80
- # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
81
- def parameterize(string, sep = '-')
82
- # replace accented chars with their ascii equivalents
74
+ # parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth"
75
+ # parameterize("^trés|Jolie-- ", separator: '_') # => "tres_jolie"
76
+ #
77
+ # To preserve the case of the characters in a string, use the `preserve_case` argument.
78
+ #
79
+ # parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth"
80
+ # parameterize("^trés|Jolie-- ", preserve_case: true) # => "tres-Jolie"
81
+ #
82
+ def parameterize(string, sep = :unused, separator: '-', preserve_case: false)
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
87
+ # Replace accented chars with their ASCII equivalents.
83
88
  parameterized_string = transliterate(string)
84
- # Turn unwanted chars into the separator
85
- parameterized_string.gsub!(/[^a-z0-9\-_]+/i, sep)
86
- unless sep.nil? || sep.empty?
87
- re_sep = Regexp.escape(sep)
89
+
90
+ # Turn unwanted chars into the separator.
91
+ parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
92
+
93
+ unless separator.nil? || separator.empty?
94
+ if separator == "-".freeze
95
+ re_duplicate_separator = /-{2,}/
96
+ re_leading_trailing_separator = /^-|-$/i
97
+ else
98
+ re_sep = Regexp.escape(separator)
99
+ re_duplicate_separator = /#{re_sep}{2,}/
100
+ re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/i
101
+ end
88
102
  # No more than one of the separator in a row.
89
- parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
103
+ parameterized_string.gsub!(re_duplicate_separator, separator)
90
104
  # Remove leading/trailing separator.
91
- parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
105
+ parameterized_string.gsub!(re_leading_trailing_separator, ''.freeze)
92
106
  end
93
- parameterized_string.downcase
107
+
108
+ parameterized_string.downcase! unless preserve_case
109
+ parameterized_string
94
110
  end
95
-
96
111
  end
97
112
  end
@@ -9,20 +9,14 @@ module ActiveSupport
9
9
  module JSON
10
10
  # matches YAML-formatted dates
11
11
  DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
12
-
12
+
13
13
  class << self
14
14
  # Parses a JSON string (JavaScript Object Notation) into a hash.
15
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"}
19
- def decode(json, options = {})
20
- if options.present?
21
- raise ArgumentError, "In Rails 4.1, ActiveSupport::JSON.decode no longer " \
22
- "accepts an options hash for MultiJSON. MultiJSON reached its end of life " \
23
- "and has been removed."
24
- end
25
-
19
+ def decode(json)
26
20
  data = ::JSON.parse(json, quirks_mode: true)
27
21
 
28
22
  if ActiveSupport.parse_json_times
@@ -1,13 +1,11 @@
1
1
  require 'active_support/core_ext/object/json'
2
2
  require 'active_support/core_ext/module/delegation'
3
- require 'active_support/deprecation'
4
3
 
5
4
  module ActiveSupport
6
5
  class << self
7
6
  delegate :use_standard_json_time_format, :use_standard_json_time_format=,
8
7
  :time_precision, :time_precision=,
9
8
  :escape_html_entities_in_json, :escape_html_entities_in_json=,
10
- :encode_big_decimal_as_string, :encode_big_decimal_as_string=,
11
9
  :json_encoder, :json_encoder=,
12
10
  :to => :'ActiveSupport::JSON::Encoding'
13
11
  end
@@ -118,54 +116,6 @@ module ActiveSupport
118
116
  # Sets the encoder used by Rails to encode Ruby objects into JSON strings
119
117
  # in +Object#to_json+ and +ActiveSupport::JSON.encode+.
120
118
  attr_accessor :json_encoder
121
-
122
- def encode_big_decimal_as_string=(as_string)
123
- message = \
124
- "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \
125
- "the new encoder will always encode them as strings.\n\n" \
126
- "You are seeing this error because you have 'active_support.encode_big_decimal_as_string' in " \
127
- "your configuration file. If you have been setting this to true, you can safely remove it from " \
128
- "your configuration. Otherwise, you should add the 'activesupport-json_encoder' gem to your " \
129
- "Gemfile in order to restore this functionality."
130
-
131
- raise NotImplementedError, message
132
- end
133
-
134
- def encode_big_decimal_as_string
135
- message = \
136
- "The JSON encoder in Rails 4.1 no longer supports encoding BigDecimals as JSON numbers. Instead, " \
137
- "the new encoder will always encode them as strings.\n\n" \
138
- "You are seeing this error because you are trying to check the value of the related configuration, " \
139
- "`active_support.encode_big_decimal_as_string`. If your application depends on this option, you should " \
140
- "add the 'activesupport-json_encoder' gem to your Gemfile. For now, this option will always be true. " \
141
- "In the future, it will be removed from Rails, so you should stop checking its value."
142
-
143
- ActiveSupport::Deprecation.warn message
144
-
145
- true
146
- end
147
-
148
- # Deprecate CircularReferenceError
149
- def const_missing(name)
150
- if name == :CircularReferenceError
151
- message = "The JSON encoder in Rails 4.1 no longer offers protection from circular references. " \
152
- "You are seeing this warning because you are rescuing from (or otherwise referencing) " \
153
- "ActiveSupport::Encoding::CircularReferenceError. In the future, this error will be " \
154
- "removed from Rails. You should remove these rescue blocks from your code and ensure " \
155
- "that your data structures are free of circular references so they can be properly " \
156
- "serialized into JSON.\n\n" \
157
- "For example, the following Hash contains a circular reference to itself:\n" \
158
- " h = {}\n" \
159
- " h['circular'] = h\n" \
160
- "In this case, calling h.to_json would not work properly."
161
-
162
- ActiveSupport::Deprecation.warn message
163
-
164
- SystemStackError
165
- else
166
- super
167
- end
168
- end
169
119
  end
170
120
 
171
121
  self.use_standard_json_time_format = true
@@ -1,8 +1,8 @@
1
- require 'thread_safe'
1
+ require 'concurrent/map'
2
2
  require 'openssl'
3
3
 
4
4
  module ActiveSupport
5
- # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2
5
+ # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2.
6
6
  # It can be used to derive a number of keys for various purposes from a given secret.
7
7
  # This lets Rails applications have a single secure secret, but avoid reusing that
8
8
  # key in multiple incompatible contexts.
@@ -24,11 +24,11 @@ module ActiveSupport
24
24
 
25
25
  # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid
26
26
  # re-executing the key generation process when it's called using the same salt and
27
- # key_size
27
+ # key_size.
28
28
  class CachingKeyGenerator
29
29
  def initialize(key_generator)
30
30
  @key_generator = key_generator
31
- @cache_keys = ThreadSafe::Cache.new
31
+ @cache_keys = Concurrent::Map.new
32
32
  end
33
33
 
34
34
  # Returns a derived key suitable for use. The default key_size is chosen
@@ -95,7 +95,7 @@ module ActiveSupport
95
95
  METHOD
96
96
  end
97
97
 
98
- # Set color by using a string or one of the defined constants. If a third
98
+ # Set color by using a symbol or one of the defined constants. If a third
99
99
  # option is set to +true+, it also adds bold to the string. This is based
100
100
  # on the Highline implementation and will automatically append CLEAR to the
101
101
  # end of the returned String.
@@ -10,7 +10,7 @@ module ActiveSupport
10
10
  # class SyncLogSubscriberTest < ActiveSupport::TestCase
11
11
  # include ActiveSupport::LogSubscriber::TestHelper
12
12
  #
13
- # def setup
13
+ # setup do
14
14
  # ActiveRecord::LogSubscriber.attach_to(:active_record)
15
15
  # end
16
16
  #
@@ -33,7 +33,7 @@ module ActiveSupport
33
33
  # you can collect them doing @logger.logged(level), where level is the level
34
34
  # used in logging, like info, debug, warn and so on.
35
35
  module TestHelper
36
- def setup
36
+ def setup # :nodoc:
37
37
  @logger = MockLogger.new
38
38
  @notifier = ActiveSupport::Notifications::Fanout.new
39
39
 
@@ -44,7 +44,7 @@ module ActiveSupport
44
44
  ActiveSupport::Notifications.notifier = @notifier
45
45
  end
46
46
 
47
- def teardown
47
+ def teardown # :nodoc:
48
48
  set_logger(nil)
49
49
  ActiveSupport::Notifications.notifier = @old_notifier
50
50
  end
@@ -1,34 +1,22 @@
1
- require 'active_support/core_ext/module/attribute_accessors'
2
1
  require 'active_support/logger_silence'
3
- require 'active_support/logger_thread_safe_level'
4
2
  require 'logger'
5
3
 
6
4
  module ActiveSupport
7
5
  class Logger < ::Logger
8
- include ActiveSupport::LoggerThreadSafeLevel
9
6
  include LoggerSilence
10
7
 
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
8
+ attr_accessor :broadcast_messages
21
9
 
22
10
  # Broadcasts logs to multiple loggers.
23
11
  def self.broadcast(logger) # :nodoc:
24
12
  Module.new do
25
13
  define_method(:add) do |*args, &block|
26
- logger.add(*args, &block)
14
+ logger.add(*args, &block) if broadcast_messages
27
15
  super(*args, &block)
28
16
  end
29
17
 
30
18
  define_method(:<<) do |x|
31
- logger << x
19
+ logger << x if broadcast_messages
32
20
  super(x)
33
21
  end
34
22
 
@@ -51,49 +39,13 @@ module ActiveSupport
51
39
  logger.level = level
52
40
  super(level)
53
41
  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
77
42
  end
78
43
  end
79
44
 
80
45
  def initialize(*args)
81
46
  super
82
47
  @formatter = SimpleFormatter.new
83
- after_initialize if respond_to? :after_initialize
84
- end
85
-
86
- def add(severity, message = nil, progname = nil, &block)
87
- return true if @logdev.nil? || (severity || UNKNOWN) < level
88
- super
89
- end
90
-
91
- Logger::Severity.constants.each do |severity|
92
- class_eval(<<-EOT, __FILE__, __LINE__ + 1)
93
- def #{severity.downcase}? # def debug?
94
- Logger::#{severity} >= level # DEBUG >= level
95
- end # end
96
- EOT
48
+ @broadcast_messages = true
97
49
  end
98
50
 
99
51
  # Simple formatter which only displays the message.
@@ -1,5 +1,5 @@
1
1
  require 'active_support/concern'
2
- require 'thread_safe'
2
+ require 'active_support/core_ext/module/attribute_accessors'
3
3
 
4
4
  module LoggerSilence
5
5
  extend ActiveSupport::Concern
@@ -13,12 +13,10 @@ module LoggerSilence
13
13
  def silence(temporary_level = Logger::ERROR)
14
14
  if silencer
15
15
  begin
16
- old_local_level = local_level
17
- self.local_level = temporary_level
18
-
16
+ old_logger_level, self.level = level, temporary_level
19
17
  yield self
20
18
  ensure
21
- self.local_level = old_local_level
19
+ self.level = old_logger_level
22
20
  end
23
21
  else
24
22
  yield self
@@ -18,8 +18,6 @@ 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
-
23
21
  module NullSerializer #:nodoc:
24
22
  def self.load(value)
25
23
  value
@@ -36,8 +34,8 @@ module ActiveSupport
36
34
  # Initialize a new MessageEncryptor. +secret+ must be at least as long as
37
35
  # the cipher key size. For the default 'aes-256-cbc' cipher, this is 256
38
36
  # bits. If you are using a user-entered secret, you can generate a suitable
39
- # key with <tt>OpenSSL::Digest::SHA256.new(user_secret).digest</tt> or
40
- # similar.
37
+ # key by using <tt>ActiveSupport::KeyGenerator</tt> or a similar key
38
+ # derivation function.
41
39
  #
42
40
  # Options:
43
41
  # * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by
@@ -66,11 +64,6 @@ module ActiveSupport
66
64
  _decrypt(verifier.verify(value))
67
65
  end
68
66
 
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
-
74
67
  private
75
68
 
76
69
  def _encrypt(value)
@@ -89,7 +82,7 @@ module ActiveSupport
89
82
 
90
83
  def _decrypt(encrypted_message)
91
84
  cipher = new_cipher
92
- encrypted_data, iv = encrypted_message.split("--").map {|v| ::Base64.strict_decode64(v)}
85
+ encrypted_data, iv = encrypted_message.split("--".freeze).map {|v| ::Base64.strict_decode64(v)}
93
86
 
94
87
  cipher.decrypt
95
88
  cipher.key = @secret
@@ -104,7 +97,7 @@ module ActiveSupport
104
97
  end
105
98
 
106
99
  def new_cipher
107
- OpenSSL::Cipher.new(@cipher)
100
+ OpenSSL::Cipher::Cipher.new(@cipher)
108
101
  end
109
102
 
110
103
  def verifier
@@ -15,7 +15,7 @@ module ActiveSupport
15
15
  # In the authentication filter:
16
16
  #
17
17
  # id, time = @verifier.verify(cookies[:remember_me])
18
- # if time < Time.now
18
+ # if Time.now < time
19
19
  # self.current_user = User.find(id)
20
20
  # end
21
21
  #
@@ -34,22 +34,78 @@ module ActiveSupport
34
34
  @serializer = options[:serializer] || Marshal
35
35
  end
36
36
 
37
- def verify(signed_message)
38
- raise InvalidSignature if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank?
37
+ # Checks if a signed message could have been generated by signing an object
38
+ # with the +MessageVerifier+'s secret.
39
+ #
40
+ # verifier = ActiveSupport::MessageVerifier.new 's3Krit'
41
+ # signed_message = verifier.generate 'a private message'
42
+ # verifier.valid_message?(signed_message) # => true
43
+ #
44
+ # tampered_message = signed_message.chop # editing the message invalidates the signature
45
+ # verifier.valid_message?(tampered_message) # => false
46
+ def valid_message?(signed_message)
47
+ return if signed_message.nil? || !signed_message.valid_encoding? || signed_message.blank?
48
+
49
+ data, digest = signed_message.split("--".freeze)
50
+ data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data))
51
+ end
39
52
 
40
- data, digest = signed_message.split("--")
41
- if data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data))
53
+ # Decodes the signed message using the +MessageVerifier+'s secret.
54
+ #
55
+ # verifier = ActiveSupport::MessageVerifier.new 's3Krit'
56
+ #
57
+ # signed_message = verifier.generate 'a private message'
58
+ # verifier.verified(signed_message) # => 'a private message'
59
+ #
60
+ # Returns +nil+ if the message was not signed with the same secret.
61
+ #
62
+ # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
63
+ # other_verifier.verified(signed_message) # => nil
64
+ #
65
+ # Returns +nil+ if the message is not Base64-encoded.
66
+ #
67
+ # invalid_message = "f--46a0120593880c733a53b6dad75b42ddc1c8996d"
68
+ # verifier.verified(invalid_message) # => nil
69
+ #
70
+ # Raises any error raised while decoding the signed message.
71
+ #
72
+ # incompatible_message = "test--dad7b06c94abba8d46a15fafaef56c327665d5ff"
73
+ # verifier.verified(incompatible_message) # => TypeError: incompatible marshal file format
74
+ def verified(signed_message)
75
+ if valid_message?(signed_message)
42
76
  begin
77
+ data = signed_message.split("--".freeze)[0]
43
78
  @serializer.load(decode(data))
44
79
  rescue ArgumentError => argument_error
45
- raise InvalidSignature if argument_error.message =~ %r{invalid base64}
80
+ return if argument_error.message =~ %r{invalid base64}
46
81
  raise
47
82
  end
48
- else
49
- raise InvalidSignature
50
83
  end
51
84
  end
52
85
 
86
+ # Decodes the signed message using the +MessageVerifier+'s secret.
87
+ #
88
+ # verifier = ActiveSupport::MessageVerifier.new 's3Krit'
89
+ # signed_message = verifier.generate 'a private message'
90
+ #
91
+ # verifier.verify(signed_message) # => 'a private message'
92
+ #
93
+ # Raises +InvalidSignature+ if the message was not signed with the same
94
+ # secret or was not Base64-encoded.
95
+ #
96
+ # other_verifier = ActiveSupport::MessageVerifier.new 'd1ff3r3nt-s3Krit'
97
+ # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
98
+ def verify(signed_message)
99
+ verified(signed_message) || raise(InvalidSignature)
100
+ end
101
+
102
+ # Generates a signed message for the provided value.
103
+ #
104
+ # The message is signed with the +MessageVerifier+'s secret. Without knowing
105
+ # the secret, the original value cannot be extracted from the message.
106
+ #
107
+ # verifier = ActiveSupport::MessageVerifier.new 's3Krit'
108
+ # verifier.generate 'a private message' # => "BAhJIhRwcml2YXRlLW1lc3NhZ2UGOgZFVA==--e2d724331ebdee96a10fb99b089508d1c72bd772"
53
109
  def generate(value)
54
110
  data = encode(@serializer.dump(value))
55
111
  "#{data}--#{generate_digest(data)}"