activerecord-session_store 1.1.1 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +27 -1
- data/lib/action_dispatch/session/active_record_store.rb +41 -27
- data/lib/active_record/session_store.rb +9 -20
- data/lib/active_record/session_store/session.rb +25 -11
- data/lib/active_record/session_store/sql_bypass.rb +11 -7
- data/lib/active_record/session_store/version.rb +1 -1
- data/lib/generators/active_record/session_migration_generator.rb +4 -0
- data/lib/generators/active_record/templates/migration.rb +1 -1
- data/lib/tasks/database.rake +5 -1
- metadata +16 -33
- data/lib/action_dispatch/session/legacy_support.rb +0 -51
- data/lib/active_record/session_store/extension/logger_silencer.rb +0 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3618fed7f080158309e682f1906af4d056b65fdbf687c7f562677cecaf17d05
|
4
|
+
data.tar.gz: 314cfae6877c80c6d73512f082765f083b733fcb5eb532b490b89033f37fd3aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd976a3e033d38632598f9ab5f47eee88c9e72fd624c470f385976361eba83b58e9b0e44241a7ce994f76b79ed3b71f142ce0d6547b10a04d5af4ed75812596d
|
7
|
+
data.tar.gz: 273a6fbec6eb0a9426d66963ee8008f91281a454fa8722d52a1f1179c1f39c68bf6a37e25ecd5db2c2031a8f344c5375121d52c8fc02fb3595654b1015057178
|
data/MIT-LICENSE
CHANGED
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
|
-
|
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::
|
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
|
-
|
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.
|
70
|
-
unless sid and session =
|
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.
|
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.
|
95
|
+
logger.silence do
|
100
96
|
if sid = current_session_id(request)
|
101
|
-
if model =
|
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.
|
124
|
-
model =
|
125
|
-
|
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
|
-
[
|
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 ||
|
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
|
-
|
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
|
-
|
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
|
@@ -108,14 +102,9 @@ module ActiveRecord
|
|
108
102
|
end
|
109
103
|
end
|
110
104
|
|
111
|
-
|
105
|
+
ActiveSupport.on_load(:active_record) do
|
106
|
+
require 'active_record/session_store/session'
|
107
|
+
end
|
108
|
+
|
112
109
|
require 'active_record/session_store/sql_bypass'
|
113
110
|
require 'active_record/session_store/railtie' if defined?(Rails)
|
114
|
-
|
115
|
-
ActionDispatch::Session::ActiveRecordStore.session_class = ActiveRecord::SessionStore::Session
|
116
|
-
Logger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
|
117
|
-
|
118
|
-
begin
|
119
|
-
require "syslog/logger"
|
120
|
-
Syslog::Logger.send :include, ActiveRecord::SessionStore::Extension::LoggerSilencer
|
121
|
-
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(
|
49
|
-
find_by_sessid(
|
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
|
@@ -103,3 +115,5 @@ module ActiveRecord
|
|
103
115
|
end
|
104
116
|
end
|
105
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
|
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 :
|
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
|
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
|
126
|
-
|
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
|
141
|
+
WHERE #{connect.quote_column_name(session_id_column)}=#{connect.quote(session_id)}
|
138
142
|
end_sql
|
139
143
|
end
|
140
144
|
end
|
data/lib/tasks/database.rake
CHANGED
@@ -1,7 +1,6 @@
|
|
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
5
|
require 'generators/active_record/session_migration_generator'
|
7
6
|
ActiveRecord::Generators::SessionMigrationGenerator.start [ ENV['MIGRATION'] || 'add_sessions_table' ]
|
@@ -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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
71
|
+
version: 2.0.8
|
72
72
|
- - "<"
|
73
73
|
- !ruby/object:Gem::Version
|
74
74
|
version: '3'
|
@@ -106,21 +106,7 @@ dependencies:
|
|
106
106
|
- - ">="
|
107
107
|
- !ruby/object:Gem::Version
|
108
108
|
version: '0'
|
109
|
-
|
110
|
-
name: appraisal
|
111
|
-
requirement: !ruby/object:Gem::Requirement
|
112
|
-
requirements:
|
113
|
-
- - "~>"
|
114
|
-
- !ruby/object:Gem::Version
|
115
|
-
version: 2.1.0
|
116
|
-
type: :development
|
117
|
-
prerelease: false
|
118
|
-
version_requirements: !ruby/object:Gem::Requirement
|
119
|
-
requirements:
|
120
|
-
- - "~>"
|
121
|
-
- !ruby/object:Gem::Version
|
122
|
-
version: 2.1.0
|
123
|
-
description:
|
109
|
+
description:
|
124
110
|
email: david@loudthinking.com
|
125
111
|
executables: []
|
126
112
|
extensions: []
|
@@ -130,9 +116,7 @@ files:
|
|
130
116
|
- MIT-LICENSE
|
131
117
|
- README.md
|
132
118
|
- lib/action_dispatch/session/active_record_store.rb
|
133
|
-
- lib/action_dispatch/session/legacy_support.rb
|
134
119
|
- lib/active_record/session_store.rb
|
135
|
-
- lib/active_record/session_store/extension/logger_silencer.rb
|
136
120
|
- lib/active_record/session_store/railtie.rb
|
137
121
|
- lib/active_record/session_store/session.rb
|
138
122
|
- lib/active_record/session_store/sql_bypass.rb
|
@@ -145,7 +129,7 @@ homepage: https://github.com/rails/activerecord-session_store
|
|
145
129
|
licenses:
|
146
130
|
- MIT
|
147
131
|
metadata: {}
|
148
|
-
post_install_message:
|
132
|
+
post_install_message:
|
149
133
|
rdoc_options:
|
150
134
|
- "--main"
|
151
135
|
- README.md
|
@@ -155,16 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
139
|
requirements:
|
156
140
|
- - ">="
|
157
141
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
142
|
+
version: 2.2.2
|
159
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
144
|
requirements:
|
161
145
|
- - ">="
|
162
146
|
- !ruby/object:Gem::Version
|
163
147
|
version: '0'
|
164
148
|
requirements: []
|
165
|
-
|
166
|
-
|
167
|
-
signing_key:
|
149
|
+
rubygems_version: 3.1.4
|
150
|
+
signing_key:
|
168
151
|
specification_version: 4
|
169
152
|
summary: An Action Dispatch session store backed by an Active Record class.
|
170
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
|