activerecord-session_store 1.0.0 → 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
- SHA1:
3
- metadata.gz: c0920d7a8356d636009b0ab31c27a96cbaad5f1b
4
- data.tar.gz: f395a9a6b74ed0c90120e971f91ea1bc5087b62f
2
+ SHA256:
3
+ metadata.gz: e3618fed7f080158309e682f1906af4d056b65fdbf687c7f562677cecaf17d05
4
+ data.tar.gz: 314cfae6877c80c6d73512f082765f083b733fcb5eb532b490b89033f37fd3aa
5
5
  SHA512:
6
- metadata.gz: e5c6788589a3c53391308c31718e1c8bf181b2bf7180ad70a1720cd9129815e5f77043ad4b51efec0b3ebbc404c4132fab404bb8a76880570c89d1948e76958d
7
- data.tar.gz: b7f0155f5446dbadf8a5c9dca98a42f24615015035991402810908b28d7fce21257eb7264c046c7596902b8a5f55f2501820541d269358c8f62d7da97067affc
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
@@ -18,12 +18,23 @@ Run the migration generator:
18
18
 
19
19
  rails generate active_record:session_migration
20
20
 
21
+ Run the migration:
22
+
23
+ rake db:migrate
24
+
21
25
  Then, set your session store in `config/initializers/session_store.rb`:
22
26
 
23
27
  ```ruby
24
28
  Rails.application.config.session_store :active_record_store, :key => '_my_app_session'
25
29
  ```
26
30
 
31
+ To avoid your sessions table expanding without limit as it will store expired and
32
+ potentially sensitive session data, it is strongly recommended in production
33
+ environments to schedule the `db:sessions:trim` rake task to run daily.
34
+ Running `bin/rake db:sessions:trim` will delete all sessions that have not
35
+ been updated in the last 30 days. The 30 days cutoff can be changed using the
36
+ `SESSION_DAYS_TRIM_THRESHOLD` environment variable.
37
+
27
38
  Configuration
28
39
  --------------
29
40
 
@@ -31,7 +42,8 @@ The default assumes a `sessions` tables with columns:
31
42
 
32
43
  * `id` (numeric primary key),
33
44
  * `session_id` (string, usually varchar; maximum length is 255), and
34
- * `data` (text or longtext; careful if your session data exceeds 65KB).
45
+ * `data` (text, longtext, json or jsonb); careful if your session data exceeds
46
+ 65KB).
35
47
 
36
48
  The `session_id` column should always be indexed for speedy lookups.
37
49
  Session data is marshaled to the `data` column in Base64 format.
@@ -53,11 +65,14 @@ having a separate `id` column if you don't want it. However, you must
53
65
  set `session.model.id = session.session_id` by hand! A before filter
54
66
  on ApplicationController is a good place.
55
67
 
56
- The serializer may be one of `marshal`, `json`, or `hybrid`. `marshal` is
57
- the default and uses the built-in Marshal methods coupled with Base64
58
- encoding. `json` does what it says on the tin, using the `parse()` and
59
- `generate()` methods of the JSON module. `hybrid` will read either type
60
- but write as JSON.
68
+ The serializer may be class responding to `#load(value)` and `#dump(value)`, or
69
+ a symbol of `marshal`, `json`, `hybrid` or `null`. `marshal` is the default and
70
+ uses the built-in Marshal methods coupled with Base64 encoding. `json` does
71
+ what it says on the tin, using the `parse()` and `generate()` methods of the
72
+ JSON module. `hybrid` will read either type but write as JSON. `null` will
73
+ not perform serialization, leaving that up to the ActiveRecord database
74
+ adapter. This allows you to take advantage of the native JSON capabilities of
75
+ your database.
61
76
 
62
77
  Since the default class is a simple Active Record, you get timestamps
63
78
  for free if you add `created_at` and `updated_at` datetime columns to
@@ -94,7 +109,33 @@ MyLogger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
94
109
  This silencer is being used to silence the logger and not leaking private
95
110
  information into the log, and it is required for security reason.
96
111
 
97
- ## 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
+ --------------
98
139
 
99
140
  Active Record Session Store is work of many contributors. You're encouraged to submit pull requests, propose features and discuss issues.
100
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 = get_session_model(request, 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,11 +1,13 @@
1
+ require 'active_record'
1
2
  require 'active_record/session_store/version'
2
3
  require 'action_dispatch/session/active_record_store'
3
- require "active_record/session_store/extension/logger_silencer"
4
4
  require 'active_support/core_ext/hash/keys'
5
5
  require 'multi_json'
6
6
 
7
7
  module ActiveRecord
8
8
  module SessionStore
9
+ autoload :Session, 'active_record/session_store/session'
10
+
9
11
  module ClassMethods # :nodoc:
10
12
  mattr_accessor :serializer
11
13
 
@@ -18,20 +20,12 @@ module ActiveRecord
18
20
  end
19
21
 
20
22
  def drop_table!
21
- if connection.schema_cache.respond_to?(:clear_data_source_cache!)
22
- connection.schema_cache.clear_data_source_cache!(table_name)
23
- else
24
- connection.schema_cache.clear_table_cache!(table_name)
25
- end
23
+ connection.schema_cache.clear_data_source_cache!(table_name)
26
24
  connection.drop_table table_name
27
25
  end
28
26
 
29
27
  def create_table!
30
- if connection.schema_cache.respond_to?(:clear_data_source_cache!)
31
- connection.schema_cache.clear_data_source_cache!(table_name)
32
- else
33
- connection.schema_cache.clear_table_cache!(table_name)
34
- end
28
+ connection.schema_cache.clear_data_source_cache!(table_name)
35
29
  connection.create_table(table_name) do |t|
36
30
  t.string session_id_column, :limit => 255
37
31
  t.text data_column_name
@@ -47,6 +41,8 @@ module ActiveRecord
47
41
  JsonSerializer
48
42
  when :hybrid then
49
43
  HybridSerializer
44
+ when :null then
45
+ NullSerializer
50
46
  else
51
47
  self.serializer
52
48
  end
@@ -91,18 +87,24 @@ module ActiveRecord
91
87
  value.start_with?(MARSHAL_SIGNATURE)
92
88
  end
93
89
  end
90
+
91
+ # Defer serialization to the ActiveRecord database adapter
92
+ class NullSerializer
93
+ def self.load(value)
94
+ value
95
+ end
96
+
97
+ def self.dump(value)
98
+ value
99
+ end
100
+ end
94
101
  end
95
102
  end
96
103
  end
97
104
 
98
- require 'active_record/session_store/session'
105
+ ActiveSupport.on_load(:active_record) do
106
+ require 'active_record/session_store/session'
107
+ end
108
+
99
109
  require 'active_record/session_store/sql_bypass'
100
110
  require 'active_record/session_store/railtie' if defined?(Rails)
101
-
102
- ActionDispatch::Session::ActiveRecordStore.session_class = ActiveRecord::SessionStore::Session
103
- Logger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
104
-
105
- begin
106
- require "syslog/logger"
107
- Syslog::Logger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
108
- 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,9 +71,32 @@ 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
- return false unless loaded?
97
+ unless loaded?
98
+ throw :abort
99
+ end
84
100
  write_attribute(@@data_column_name, self.class.serialize(data))
85
101
  end
86
102
 
@@ -88,7 +104,9 @@ module ActiveRecord
88
104
  # larger than the data storage column. Raises
89
105
  # ActionController::SessionOverflowError.
90
106
  def raise_on_session_data_overflow!
91
- return false unless loaded?
107
+ unless loaded?
108
+ throw :abort
109
+ end
92
110
  limit = self.class.data_column_size_limit
93
111
  if limit and read_attribute(@@data_column_name).size > limit
94
112
  raise ActionController::SessionOverflowError
@@ -97,3 +115,5 @@ module ActiveRecord
97
115
  end
98
116
  end
99
117
  end
118
+
119
+ ActionDispatch::Session::ActiveRecordStore.session_class = ActiveRecord::SessionStore::Session
@@ -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.0.0'
3
+ VERSION = "2.0.0".freeze
4
4
  end
5
5
  end
@@ -19,6 +19,10 @@ module ActiveRecord
19
19
  end
20
20
  current_table_name
21
21
  end
22
+
23
+ def migration_version
24
+ "[#{ActiveRecord::Migration.current_version}]"
25
+ end
22
26
  end
23
27
  end
24
28
  end
@@ -1,4 +1,4 @@
1
- class <%= migration_class_name %> < ActiveRecord::Migration
1
+ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version %>
2
2
  def change
3
3
  create_table :<%= session_table_name %> do |t|
4
4
  t.string :session_id, :null => false
@@ -1,15 +1,14 @@
1
1
  namespace 'db:sessions' do
2
2
  desc "Creates a sessions migration for use with ActiveRecord::SessionStore"
3
3
  task :create => [:environment, 'db:load_config'] do
4
- raise 'Task unavailable to this database (no migration support)' unless ActiveRecord::Base.connection.supports_migrations?
5
4
  Rails.application.load_generators
6
- require 'rails/generators/rails/session_migration/session_migration_generator'
7
- Rails::Generators::SessionMigrationGenerator.start [ ENV['MIGRATION'] || 'add_sessions_table' ]
5
+ require 'generators/active_record/session_migration_generator'
6
+ ActiveRecord::Generators::SessionMigrationGenerator.start [ ENV['MIGRATION'] || 'add_sessions_table' ]
8
7
  end
9
8
 
10
9
  desc "Clear the sessions table"
11
10
  task :clear => [:environment, 'db:load_config'] do
12
- ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::SessionStore::Session.table_name}"
11
+ ActiveRecord::Base.connection.execute "TRUNCATE TABLE #{ActiveRecord::SessionStore::Session.table_name}"
13
12
  end
14
13
 
15
14
  desc "Trim old sessions from the table (default: > 30 days)"
@@ -19,4 +18,9 @@ namespace 'db:sessions' do
19
18
  where("updated_at < ?", cutoff_period).
20
19
  delete_all
21
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
22
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.0.0
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: 2016-05-16 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,67 +16,49 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '5.1'
19
+ version: 5.2.4.1
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: '4.0'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '5.1'
26
+ version: 5.2.4.1
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: actionpack
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
31
  - - ">="
38
32
  - !ruby/object:Gem::Version
39
- version: '4.0'
40
- - - "<"
41
- - !ruby/object:Gem::Version
42
- version: '5.1'
33
+ version: 5.2.4.1
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
46
37
  requirements:
47
38
  - - ">="
48
39
  - !ruby/object:Gem::Version
49
- version: '4.0'
50
- - - "<"
51
- - !ruby/object:Gem::Version
52
- version: '5.1'
40
+ version: 5.2.4.1
53
41
  - !ruby/object:Gem::Dependency
54
42
  name: railties
55
43
  requirement: !ruby/object:Gem::Requirement
56
44
  requirements:
57
45
  - - ">="
58
46
  - !ruby/object:Gem::Version
59
- version: '4.0'
60
- - - "<"
61
- - !ruby/object:Gem::Version
62
- version: '5.1'
47
+ version: 5.2.4.1
63
48
  type: :runtime
64
49
  prerelease: false
65
50
  version_requirements: !ruby/object:Gem::Requirement
66
51
  requirements:
67
52
  - - ">="
68
53
  - !ruby/object:Gem::Version
69
- version: '4.0'
70
- - - "<"
71
- - !ruby/object:Gem::Version
72
- version: '5.1'
54
+ version: 5.2.4.1
73
55
  - !ruby/object:Gem::Dependency
74
56
  name: rack
75
57
  requirement: !ruby/object:Gem::Requirement
76
58
  requirements:
77
59
  - - ">="
78
60
  - !ruby/object:Gem::Version
79
- version: 1.5.2
61
+ version: 2.0.8
80
62
  - - "<"
81
63
  - !ruby/object:Gem::Version
82
64
  version: '3'
@@ -86,7 +68,7 @@ dependencies:
86
68
  requirements:
87
69
  - - ">="
88
70
  - !ruby/object:Gem::Version
89
- version: 1.5.2
71
+ version: 2.0.8
90
72
  - - "<"
91
73
  - !ruby/object:Gem::Version
92
74
  version: '3'
@@ -124,21 +106,7 @@ dependencies:
124
106
  - - ">="
125
107
  - !ruby/object:Gem::Version
126
108
  version: '0'
127
- - !ruby/object:Gem::Dependency
128
- name: appraisal
129
- requirement: !ruby/object:Gem::Requirement
130
- requirements:
131
- - - "~>"
132
- - !ruby/object:Gem::Version
133
- version: 2.1.0
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- requirements:
138
- - - "~>"
139
- - !ruby/object:Gem::Version
140
- version: 2.1.0
141
- description:
109
+ description:
142
110
  email: david@loudthinking.com
143
111
  executables: []
144
112
  extensions: []
@@ -148,9 +116,7 @@ files:
148
116
  - MIT-LICENSE
149
117
  - README.md
150
118
  - lib/action_dispatch/session/active_record_store.rb
151
- - lib/action_dispatch/session/legacy_support.rb
152
119
  - lib/active_record/session_store.rb
153
- - lib/active_record/session_store/extension/logger_silencer.rb
154
120
  - lib/active_record/session_store/railtie.rb
155
121
  - lib/active_record/session_store/session.rb
156
122
  - lib/active_record/session_store/sql_bypass.rb
@@ -163,7 +129,7 @@ homepage: https://github.com/rails/activerecord-session_store
163
129
  licenses:
164
130
  - MIT
165
131
  metadata: {}
166
- post_install_message:
132
+ post_install_message:
167
133
  rdoc_options:
168
134
  - "--main"
169
135
  - README.md
@@ -173,16 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
139
  requirements:
174
140
  - - ">="
175
141
  - !ruby/object:Gem::Version
176
- version: 1.9.3
142
+ version: 2.2.2
177
143
  required_rubygems_version: !ruby/object:Gem::Requirement
178
144
  requirements:
179
145
  - - ">="
180
146
  - !ruby/object:Gem::Version
181
147
  version: '0'
182
148
  requirements: []
183
- rubyforge_project:
184
- rubygems_version: 2.5.1
185
- signing_key:
149
+ rubygems_version: 3.1.4
150
+ signing_key:
186
151
  specification_version: 4
187
152
  summary: An Action Dispatch session store backed by an Active Record class.
188
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