activerecord-session_store 1.1.3 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af08a0134b3e5a615c2d9f400c30c9d0b4f5327e21c1254f49cfec775ef73732
4
- data.tar.gz: f6dd6871a3df37d22cc652b54b3f76f41746d9f0c5e01920984a3bcc6d516cf6
3
+ metadata.gz: e3618fed7f080158309e682f1906af4d056b65fdbf687c7f562677cecaf17d05
4
+ data.tar.gz: 314cfae6877c80c6d73512f082765f083b733fcb5eb532b490b89033f37fd3aa
5
5
  SHA512:
6
- metadata.gz: 300394f621b26e545ba842e3d8c4a78f733cd34768ede33ab07f7f4abfc168fc1fa60c4b10ea47a7046db896395206201e3a0b0aa1680418bd219998ebbd5b46
7
- data.tar.gz: f4fd30af09711cc74e0a7365c6c529c99a1cd47a4aa91f8c0314deb4eb0cd552d8b3824e497e5d9af86ac110c98f3b9d5865b771af1db12993401774bdfd7422
6
+ metadata.gz: cd976a3e033d38632598f9ab5f47eee88c9e72fd624c470f385976361eba83b58e9b0e44241a7ce994f76b79ed3b71f142ce0d6547b10a04d5af4ed75812596d
7
+ data.tar.gz: 273a6fbec6eb0a9426d66963ee8008f91281a454fa8722d52a1f1179c1f39c68bf6a37e25ecd5db2c2031a8f344c5375121d52c8fc02fb3595654b1015057178
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012-2016 David Heinemeier Hansson
1
+ Copyright (c) 2012-2019 David Heinemeier Hansson
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -109,7 +109,33 @@ MyLogger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
109
109
  This silencer is being used to silence the logger and not leaking private
110
110
  information into the log, and it is required for security reason.
111
111
 
112
- ## Contributing to Active Record Session Store
112
+ CVE-2015-9284 mitigation
113
+ --------------
114
+
115
+ Sessions that were created by Active Record Session Store version 1.x are
116
+ affected by [CVE-2019-25025]. This means an attacker can perform a timing
117
+ attack against the session IDs stored in the database.
118
+
119
+ [CVE-2019-25025]: https://github.com/advisories/GHSA-cvw2-xj8r-mjf7
120
+
121
+ After upgrade to version 2.0.0, you should run [`db:sessions:upgrade`] rake task
122
+ to upgrade all existing session records in your database to the secured version.
123
+
124
+ [`db:sessions:upgrade`]: https://github.com/rails/activerecord-session_store/blob/master/lib/tasks/database.rake#L22
125
+
126
+ ```console
127
+ $ rake db:sessions:upgrade
128
+ ```
129
+
130
+ This rake task is idempotent and can be run multiple times, and session data of
131
+ users will remain intact.
132
+
133
+ Please see [#151] for more details.
134
+
135
+ [#151]: https://github.com/rails/activerecord-session_store/pull/151
136
+
137
+ Contributing to Active Record Session Store
138
+ --------------
113
139
 
114
140
  Active Record Session Store is work of many contributors. You're encouraged to submit pull requests, propose features and discuss issues.
115
141
 
@@ -52,26 +52,22 @@ module ActionDispatch
52
52
  #
53
53
  # The example SqlBypass class is a generic SQL session store. You may
54
54
  # use it as a basis for high-performance database-specific stores.
55
- class ActiveRecordStore < ActionDispatch::Session::AbstractStore
55
+ class ActiveRecordStore < ActionDispatch::Session::AbstractSecureStore
56
56
  # The class used for session storage. Defaults to
57
57
  # ActiveRecord::SessionStore::Session
58
58
  cattr_accessor :session_class
59
59
 
60
60
  SESSION_RECORD_KEY = 'rack.session.record'
61
- if Rack.const_defined?(:RACK_SESSION_OPTIONS)
62
- ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS
63
- else
64
- ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY
65
- end
61
+ ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS
66
62
 
67
63
  private
68
64
  def get_session(request, sid)
69
- logger.silence_logger do
70
- unless sid and session = @@session_class.find_by_session_id(sid)
65
+ logger.silence do
66
+ unless sid and session = get_session_with_fallback(sid)
71
67
  # If the sid was nil or if there is no pre-existing session under the sid,
72
68
  # force the generation of a new sid and associate a new session associated with the new sid
73
69
  sid = generate_sid
74
- session = @@session_class.new(:session_id => sid, :data => {})
70
+ session = @@session_class.new(:session_id => sid.private_id, :data => {})
75
71
  end
76
72
  request.env[SESSION_RECORD_KEY] = session
77
73
  [sid, session.data]
@@ -79,8 +75,8 @@ module ActionDispatch
79
75
  end
80
76
 
81
77
  def write_session(request, sid, session_data, options)
82
- logger.silence_logger do
83
- record = get_session_model(request, sid)
78
+ logger.silence do
79
+ record, sid = get_session_model(request, sid)
84
80
  record.data = session_data
85
81
  return false unless record.save
86
82
 
@@ -96,9 +92,9 @@ module ActionDispatch
96
92
  end
97
93
 
98
94
  def delete_session(request, session_id, options)
99
- logger.silence_logger do
95
+ logger.silence do
100
96
  if sid = current_session_id(request)
101
- if model = @@session_class.find_by_session_id(sid)
97
+ if model = get_session_with_fallback(sid)
102
98
  data = model.data
103
99
  model.destroy
104
100
  end
@@ -110,7 +106,7 @@ module ActionDispatch
110
106
  new_sid = generate_sid
111
107
 
112
108
  if options[:renew]
113
- new_model = @@session_class.new(:session_id => new_sid, :data => data)
109
+ new_model = @@session_class.new(:session_id => new_sid.private_id, :data => data)
114
110
  new_model.save
115
111
  request.env[SESSION_RECORD_KEY] = new_model
116
112
  end
@@ -120,11 +116,11 @@ module ActionDispatch
120
116
  end
121
117
 
122
118
  def get_session_model(request, id)
123
- logger.silence_logger do
124
- model = @@session_class.find_by_session_id(id)
125
- if !model
119
+ logger.silence do
120
+ model = get_session_with_fallback(id)
121
+ unless model
126
122
  id = generate_sid
127
- model = @@session_class.new(:session_id => id, :data => {})
123
+ model = @@session_class.new(:session_id => id.private_id, :data => {})
128
124
  model.save
129
125
  end
130
126
  if request.env[ENV_SESSION_OPTIONS_KEY][:id].nil?
@@ -132,23 +128,41 @@ module ActionDispatch
132
128
  else
133
129
  request.env[SESSION_RECORD_KEY] ||= model
134
130
  end
135
- model
131
+ [model, id]
132
+ end
133
+ end
134
+
135
+ def get_session_with_fallback(sid)
136
+ if sid && !self.class.private_session_id?(sid.public_id)
137
+ if (secure_session = @@session_class.find_by_session_id(sid.private_id))
138
+ secure_session
139
+ elsif (insecure_session = @@session_class.find_by_session_id(sid.public_id))
140
+ insecure_session.session_id = sid.private_id # this causes the session to be secured
141
+ insecure_session
142
+ end
136
143
  end
137
144
  end
138
145
 
139
146
  def find_session(request, id)
140
- model = get_session_model(request, id)
141
- [model.session_id, model.data]
147
+ model, id = get_session_model(request, id)
148
+ [id, model.data]
149
+ end
150
+
151
+ module NilLogger
152
+ def self.silence
153
+ yield
154
+ end
142
155
  end
143
156
 
144
157
  def logger
145
- ActiveRecord::Base.logger || ActiveRecord::SessionStore::NilLogger
158
+ ActiveRecord::Base.logger || NilLogger
159
+ end
160
+
161
+ def self.private_session_id?(session_id)
162
+ # user tried to retrieve a session by a private key?
163
+ session_id =~ /\A\d+::/
146
164
  end
165
+
147
166
  end
148
167
  end
149
168
  end
150
-
151
- if ActiveRecord::VERSION::MAJOR == 4
152
- require 'action_dispatch/session/legacy_support'
153
- ActionDispatch::Session::ActiveRecordStore.send(:include, ActionDispatch::Session::LegacySupport)
154
- end
@@ -1,7 +1,6 @@
1
1
  require 'active_record'
2
2
  require 'active_record/session_store/version'
3
3
  require 'action_dispatch/session/active_record_store'
4
- require "active_record/session_store/extension/logger_silencer"
5
4
  require 'active_support/core_ext/hash/keys'
6
5
  require 'multi_json'
7
6
 
@@ -21,20 +20,12 @@ module ActiveRecord
21
20
  end
22
21
 
23
22
  def drop_table!
24
- if connection.schema_cache.respond_to?(:clear_data_source_cache!)
25
- connection.schema_cache.clear_data_source_cache!(table_name)
26
- else
27
- connection.schema_cache.clear_table_cache!(table_name)
28
- end
23
+ connection.schema_cache.clear_data_source_cache!(table_name)
29
24
  connection.drop_table table_name
30
25
  end
31
26
 
32
27
  def create_table!
33
- if connection.schema_cache.respond_to?(:clear_data_source_cache!)
34
- connection.schema_cache.clear_data_source_cache!(table_name)
35
- else
36
- connection.schema_cache.clear_table_cache!(table_name)
37
- end
28
+ connection.schema_cache.clear_data_source_cache!(table_name)
38
29
  connection.create_table(table_name) do |t|
39
30
  t.string session_id_column, :limit => 255
40
31
  t.text data_column_name
@@ -117,10 +108,3 @@ end
117
108
 
118
109
  require 'active_record/session_store/sql_bypass'
119
110
  require 'active_record/session_store/railtie' if defined?(Rails)
120
-
121
- Logger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
122
-
123
- begin
124
- require "syslog/logger"
125
- Syslog::Logger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
126
- rescue LoadError; end
@@ -17,13 +17,6 @@ module ActiveRecord
17
17
  before_save :serialize_data!
18
18
  before_save :raise_on_session_data_overflow!
19
19
 
20
- # This method is defiend in `protected_attributes` gem. We can't check for
21
- # `attr_accessible` as Rails also define this and raise `RuntimeError`
22
- # telling you to use the gem.
23
- if respond_to?(:accessible_attributes)
24
- attr_accessible :session_id, :data
25
- end
26
-
27
20
  class << self
28
21
  def data_column_size_limit
29
22
  @data_column_size_limit ||= columns_hash[data_column_name].limit
@@ -45,8 +38,8 @@ module ActiveRecord
45
38
  # Reset column info since it may be stale.
46
39
  reset_column_information
47
40
  if columns_hash['sessid']
48
- def self.find_by_session_id(*args)
49
- find_by_sessid(*args)
41
+ def self.find_by_session_id(session_id)
42
+ find_by_sessid(session_id)
50
43
  end
51
44
 
52
45
  define_method(:session_id) { sessid }
@@ -78,10 +71,30 @@ module ActiveRecord
78
71
  @data
79
72
  end
80
73
 
74
+ # This method was introduced when addressing CVE-2019-16782
75
+ # (see https://github.com/rack/rack/security/advisories/GHSA-hrqr-hxpp-chr3).
76
+ # Sessions created on version <= 1.1.3 were guessable via a timing attack.
77
+ # To secure sessions created on those old versions, this method can be called
78
+ # on all existing sessions in the database. Users will not lose their session
79
+ # when this is done.
80
+ def secure!
81
+ session_id_column = if self.class.columns_hash['sessid']
82
+ :sessid
83
+ else
84
+ :session_id
85
+ end
86
+ raw_session_id = read_attribute(session_id_column)
87
+ if ActionDispatch::Session::ActiveRecordStore.private_session_id?(raw_session_id)
88
+ # is already private, nothing to do
89
+ else
90
+ session_id_object = Rack::Session::SessionId.new(raw_session_id)
91
+ update_column(session_id_column, session_id_object.private_id)
92
+ end
93
+ end
94
+
81
95
  private
82
96
  def serialize_data!
83
97
  unless loaded?
84
- return false if Rails::VERSION::MAJOR < 5
85
98
  throw :abort
86
99
  end
87
100
  write_attribute(@@data_column_name, self.class.serialize(data))
@@ -92,7 +105,6 @@ module ActiveRecord
92
105
  # ActionController::SessionOverflowError.
93
106
  def raise_on_session_data_overflow!
94
107
  unless loaded?
95
- return false if Rails::VERSION::MAJOR < 5
96
108
  throw :abort
97
109
  end
98
110
  limit = self.class.data_column_size_limit
@@ -60,15 +60,16 @@ module ActiveRecord
60
60
 
61
61
  # Look up a session by id and deserialize its data if found.
62
62
  def find_by_session_id(session_id)
63
- if record = connection.select_one("SELECT #{connection.quote_column_name(data_column)} AS data FROM #{@@table_name} WHERE #{connection.quote_column_name(@@session_id_column)}=#{connection.quote(session_id.to_s)}")
64
- new(:session_id => session_id, :serialized_data => record['data'])
63
+ if record = connection.select_one("SELECT #{connection.quote_column_name(data_column)} AS data FROM #{@@table_name} WHERE #{connection.quote_column_name(@@session_id_column)}=#{connection.quote(session_id)}")
64
+ new(:session_id => session_id, :retrieved_by => session_id, :serialized_data => record['data'])
65
65
  end
66
66
  end
67
67
  end
68
68
 
69
69
  delegate :connection, :connection=, :connection_pool, :connection_pool=, :to => self
70
70
 
71
- attr_reader :session_id, :new_record
71
+ attr_reader :new_record
72
+ attr_accessor :session_id
72
73
  alias :new_record? :new_record
73
74
 
74
75
  attr_writer :data
@@ -77,7 +78,8 @@ module ActiveRecord
77
78
  # telling us to postpone deserializing until the data is requested.
78
79
  # We need to handle a normal data attribute in case of a new record.
79
80
  def initialize(attributes)
80
- @session_id = attributes[:session_id]
81
+ @session_id = attributes[:session_id]
82
+ @retrieved_by = attributes[:retrieved_by]
81
83
  @data = attributes[:data]
82
84
  @serialized_data = attributes[:serialized_data]
83
85
  @new_record = @serialized_data.nil?
@@ -122,8 +124,10 @@ module ActiveRecord
122
124
  else
123
125
  connect.update <<-end_sql, 'Update session'
124
126
  UPDATE #{table_name}
125
- SET #{connect.quote_column_name(data_column)}=#{connect.quote(serialized_data)}
126
- WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)}
127
+ SET
128
+ #{connect.quote_column_name(data_column)}=#{connect.quote(serialized_data)},
129
+ #{connect.quote_column_name(session_id_column)}=#{connect.quote(@session_id)}
130
+ WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(@retrieved_by)}
127
131
  end_sql
128
132
  end
129
133
  end
@@ -134,7 +138,7 @@ module ActiveRecord
134
138
  connect = connection
135
139
  connect.delete <<-end_sql, 'Destroy session'
136
140
  DELETE FROM #{table_name}
137
- WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id.to_s)}
141
+ WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)}
138
142
  end_sql
139
143
  end
140
144
  end
@@ -1,5 +1,5 @@
1
1
  module ActiveRecord
2
2
  module SessionStore
3
- VERSION = "1.1.3".freeze
3
+ VERSION = "2.0.0".freeze
4
4
  end
5
5
  end
@@ -21,7 +21,7 @@ module ActiveRecord
21
21
  end
22
22
 
23
23
  def migration_version
24
- "[#{ActiveRecord::Migration.current_version}]" if ActiveRecord::Migration.respond_to?(:current_version)
24
+ "[#{ActiveRecord::Migration.current_version}]"
25
25
  end
26
26
  end
27
27
  end
@@ -18,4 +18,9 @@ namespace 'db:sessions' do
18
18
  where("updated_at < ?", cutoff_period).
19
19
  delete_all
20
20
  end
21
+
22
+ desc "Upgrade current sessions in the database to the secure version"
23
+ task :upgrade => [:environment, 'db:load_config'] do
24
+ ActionDispatch::Session::ActiveRecordStore.session_class.find_each(&:secure!)
25
+ end
21
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-session_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.3
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-23 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,49 +16,49 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
19
+ version: 5.2.4.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.0'
26
+ version: 5.2.4.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: actionpack
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4.0'
33
+ version: 5.2.4.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '4.0'
40
+ version: 5.2.4.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: railties
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '4.0'
47
+ version: 5.2.4.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '4.0'
54
+ version: 5.2.4.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rack
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 1.5.2
61
+ version: 2.0.8
62
62
  - - "<"
63
63
  - !ruby/object:Gem::Version
64
64
  version: '3'
@@ -68,7 +68,7 @@ dependencies:
68
68
  requirements:
69
69
  - - ">="
70
70
  - !ruby/object:Gem::Version
71
- version: 1.5.2
71
+ version: 2.0.8
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '3'
@@ -106,7 +106,7 @@ dependencies:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
108
  version: '0'
109
- description:
109
+ description:
110
110
  email: david@loudthinking.com
111
111
  executables: []
112
112
  extensions: []
@@ -116,9 +116,7 @@ files:
116
116
  - MIT-LICENSE
117
117
  - README.md
118
118
  - lib/action_dispatch/session/active_record_store.rb
119
- - lib/action_dispatch/session/legacy_support.rb
120
119
  - lib/active_record/session_store.rb
121
- - lib/active_record/session_store/extension/logger_silencer.rb
122
120
  - lib/active_record/session_store/railtie.rb
123
121
  - lib/active_record/session_store/session.rb
124
122
  - lib/active_record/session_store/sql_bypass.rb
@@ -131,7 +129,7 @@ homepage: https://github.com/rails/activerecord-session_store
131
129
  licenses:
132
130
  - MIT
133
131
  metadata: {}
134
- post_install_message:
132
+ post_install_message:
135
133
  rdoc_options:
136
134
  - "--main"
137
135
  - README.md
@@ -141,15 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
141
139
  requirements:
142
140
  - - ">="
143
141
  - !ruby/object:Gem::Version
144
- version: 1.9.3
142
+ version: 2.2.2
145
143
  required_rubygems_version: !ruby/object:Gem::Requirement
146
144
  requirements:
147
145
  - - ">="
148
146
  - !ruby/object:Gem::Version
149
147
  version: '0'
150
148
  requirements: []
151
- rubygems_version: 3.0.3
152
- signing_key:
149
+ rubygems_version: 3.1.4
150
+ signing_key:
153
151
  specification_version: 4
154
152
  summary: An Action Dispatch session store backed by an Active Record class.
155
153
  test_files: []
@@ -1,51 +0,0 @@
1
- module ActionDispatch
2
- module Session
3
- module LegacySupport
4
- EnvWrapper = Struct.new(:env)
5
-
6
- def self.included(klass)
7
- [
8
- :get_session,
9
- :get_session_model,
10
- :write_session,
11
- :delete_session,
12
- :find_session
13
- ].each do |m|
14
- klass.send(:alias_method, "#{m}_rails5".to_sym, m)
15
- klass.send(:remove_method, m)
16
- end
17
- end
18
-
19
- def get_session(env, sid)
20
- request = EnvWrapper.new(env)
21
- get_session_rails5(request, sid)
22
- end
23
-
24
- def set_session(env, sid, session_data, options)
25
- request = EnvWrapper.new(env)
26
- write_session_rails5(request, sid, session_data, options)
27
- end
28
-
29
- def destroy_session(env, session_id, options)
30
- request = EnvWrapper.new(env)
31
- if sid = current_session_id(request.env)
32
- get_session_model(request, sid).destroy
33
- request.env[self.class::SESSION_RECORD_KEY] = nil
34
- end
35
- generate_sid unless options[:drop]
36
- end
37
-
38
- def get_session_model(request, sid)
39
- if request.env[self.class::ENV_SESSION_OPTIONS_KEY][:id].nil?
40
- request.env[self.class::SESSION_RECORD_KEY] = find_session(sid)
41
- else
42
- request.env[self.class::SESSION_RECORD_KEY] ||= find_session(sid)
43
- end
44
- end
45
-
46
- def find_session(id)
47
- self.class.session_class.find_by_session_id(id) || self.class.session_class.new(:session_id => id, :data => {})
48
- end
49
- end
50
- end
51
- end
@@ -1,78 +0,0 @@
1
- require "thread"
2
- require "active_support/core_ext/class/attribute_accessors"
3
- require "active_support/core_ext/module/aliasing"
4
- require "active_support/core_ext/module/attribute_accessors"
5
- require "active_support/concern"
6
-
7
- module ActiveRecord
8
- module SessionStore
9
- module Extension
10
- module LoggerSilencer
11
- extend ActiveSupport::Concern
12
-
13
- included do
14
- cattr_accessor :silencer
15
- self.silencer = true
16
- alias_method :level_without_threadsafety, :level
17
- alias_method :level, :level_with_threadsafety
18
- alias_method :add_without_threadsafety, :add
19
- alias_method :add, :add_with_threadsafety
20
- end
21
-
22
- def thread_level
23
- Thread.current[thread_hash_level_key]
24
- end
25
-
26
- def thread_level=(level)
27
- Thread.current[thread_hash_level_key] = level
28
- end
29
-
30
- def level_with_threadsafety
31
- thread_level || level_without_threadsafety
32
- end
33
-
34
- def add_with_threadsafety(severity, message = nil, progname = nil, &block)
35
- if (defined?(@logdev) && @logdev.nil?) || (severity || UNKNOWN) < level
36
- true
37
- else
38
- add_without_threadsafety(severity, message, progname, &block)
39
- end
40
- end
41
-
42
- # Silences the logger for the duration of the block.
43
- def silence_logger(temporary_level = Logger::ERROR)
44
- if silencer
45
- begin
46
- self.thread_level = temporary_level
47
- yield self
48
- ensure
49
- self.thread_level = nil
50
- end
51
- else
52
- yield self
53
- end
54
- end
55
-
56
- for severity in Logger::Severity.constants
57
- class_eval <<-EOT, __FILE__, __LINE__ + 1
58
- def #{severity.downcase}? # def debug?
59
- Logger::#{severity} >= level # DEBUG >= level
60
- end # end
61
- EOT
62
- end
63
-
64
- private
65
-
66
- def thread_hash_level_key
67
- @thread_hash_level_key ||= :"ThreadSafeLogger##{object_id}@level"
68
- end
69
- end
70
- end
71
-
72
- class NilLogger
73
- def self.silence_logger
74
- yield
75
- end
76
- end
77
- end
78
- end