activerecord-session_store 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +48 -7
- data/lib/action_dispatch/session/active_record_store.rb +41 -27
- data/lib/active_record/session_store.rb +22 -20
- data/lib/active_record/session_store/session.rb +31 -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 +8 -4
- metadata +16 -51
- 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
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
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
@@ -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
|
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
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
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::
|
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
|
@@ -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
|
-
|
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(
|
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,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
|
-
|
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
|
-
|
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
|
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,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 '
|
7
|
-
|
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 "
|
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:
|
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,67 +16,49 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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:
|
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
|
-
|
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:
|
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
|
-
|
184
|
-
|
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
|