redis-session-store 0.11.4 → 0.11.6
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 +4 -4
- data/.github/workflows/ruby.yml +10 -2
- data/.rubocop.yml +4 -1
- data/AUTHORS.md +2 -0
- data/CHANGELOG.md +11 -0
- data/README.md +5 -9
- data/lib/redis-session-store.rb +33 -14
- data/redis-session-store.gemspec +2 -2
- data/spec/redis_session_store_spec.rb +93 -24
- data/spec/support.rb +24 -2
- metadata +9 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d18e9f3e69775d747faf496a6dcd718aaae738759306fc85fb158e0670de9588
|
4
|
+
data.tar.gz: bd5457371142d59eb6b2009b6b3add32efcc57bb886ec6e05b415298031ad9d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69db8ffaf3ba8bfa9002f2355474b213ab9e7091338eeb63e3049ea31e575a461ed770e6024be89a925dccbaf8a1b4f62b261e5b927b30b1ef041f3e92d9f275
|
7
|
+
data.tar.gz: 3f4af5b4cd6b806c44407d2ad8fd536873c03fc72db4e20a386afaffc3a681a98ab7c7755b478c56d656c71439d1a44b651413d92ec01d3c6a60b4824d971c61
|
data/.github/workflows/ruby.yml
CHANGED
@@ -19,10 +19,18 @@ jobs:
|
|
19
19
|
runs-on: ubuntu-latest
|
20
20
|
strategy:
|
21
21
|
matrix:
|
22
|
-
ruby:
|
22
|
+
ruby:
|
23
|
+
- 2.5
|
24
|
+
- 2.6
|
25
|
+
- 2.7
|
26
|
+
- '3.0'
|
27
|
+
- 3.1
|
28
|
+
- head
|
29
|
+
- jruby-9.2.20.1
|
30
|
+
- jruby-head
|
23
31
|
|
24
32
|
steps:
|
25
|
-
- uses: actions/checkout@
|
33
|
+
- uses: actions/checkout@v3
|
26
34
|
- name: Set up Ruby
|
27
35
|
uses: ruby/setup-ruby@v1
|
28
36
|
with:
|
data/.rubocop.yml
CHANGED
data/AUTHORS.md
CHANGED
@@ -2,6 +2,7 @@ Redis Session Store authors
|
|
2
2
|
===========================
|
3
3
|
|
4
4
|
- Ben Marini
|
5
|
+
- Bill Ruddock
|
5
6
|
- Dan Buch
|
6
7
|
- Donald Plummer
|
7
8
|
- Edwin Cruz
|
@@ -24,3 +25,4 @@ Redis Session Store authors
|
|
24
25
|
- Peter Karman
|
25
26
|
- Zach Margolis
|
26
27
|
- Zachary Belzer
|
28
|
+
- Yutaka Kamei
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,17 @@
|
|
4
4
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
|
+
# [0.11.6] - 2024-11-12
|
8
|
+
- Fix secure session using private_id
|
9
|
+
- Support Rails 8
|
10
|
+
|
11
|
+
# [0.11.5] - 2022-11-27
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
|
15
|
+
- Support redis 5
|
16
|
+
- Actionpack more than or equal to 6
|
17
|
+
|
7
18
|
## [0.11.4] - 2022-01-29
|
8
19
|
### Fixed
|
9
20
|
- Use AbstractSecureStore for security fix
|
data/README.md
CHANGED
@@ -32,7 +32,7 @@ See `lib/redis-session-store.rb` for a list of valid options.
|
|
32
32
|
In your Rails app, throw in an initializer with the following contents:
|
33
33
|
|
34
34
|
``` ruby
|
35
|
-
Rails.application.config.session_store :redis_session_store,
|
35
|
+
Rails.application.config.session_store :redis_session_store,
|
36
36
|
key: 'your_session_key',
|
37
37
|
redis: {
|
38
38
|
expire_after: 120.minutes, # cookie expiration
|
@@ -40,7 +40,6 @@ Rails.application.config.session_store :redis_session_store, {
|
|
40
40
|
key_prefix: 'myapp:session:',
|
41
41
|
url: 'redis://localhost:6379/0',
|
42
42
|
}
|
43
|
-
}
|
44
43
|
```
|
45
44
|
|
46
45
|
### Redis unavailability handling
|
@@ -49,13 +48,12 @@ If you want to handle cases where Redis is unavailable, a custom
|
|
49
48
|
callable handler may be provided as `on_redis_down`:
|
50
49
|
|
51
50
|
``` ruby
|
52
|
-
Rails.application.config.session_store :redis_session_store,
|
51
|
+
Rails.application.config.session_store :redis_session_store,
|
53
52
|
# ... other options ...
|
54
53
|
on_redis_down: ->(e, env, sid) { do_something_will_ya!(e) }
|
55
54
|
redis: {
|
56
55
|
# ... redis options ...
|
57
56
|
}
|
58
|
-
}
|
59
57
|
```
|
60
58
|
|
61
59
|
### Serializer
|
@@ -69,13 +67,12 @@ custom serializer:
|
|
69
67
|
* `CustomClass` - You can just pass the constant name of any class that responds to `.load` and `.dump`
|
70
68
|
|
71
69
|
``` ruby
|
72
|
-
Rails.application.config.session_store :redis_session_store,
|
70
|
+
Rails.application.config.session_store :redis_session_store,
|
73
71
|
# ... other options ...
|
74
72
|
serializer: :hybrid
|
75
73
|
redis: {
|
76
74
|
# ... redis options ...
|
77
75
|
}
|
78
|
-
}
|
79
76
|
```
|
80
77
|
|
81
78
|
**Note**: Rails 4 is required for using the `:json` and `:hybrid` serializers
|
@@ -88,20 +85,19 @@ custom callable handler may be provided as `on_session_load_error` which
|
|
88
85
|
will be given the error and the session ID.
|
89
86
|
|
90
87
|
``` ruby
|
91
|
-
Rails.application.config.session_store :redis_session_store,
|
88
|
+
Rails.application.config.session_store :redis_session_store,
|
92
89
|
# ... other options ...
|
93
90
|
on_session_load_error: ->(e, sid) { do_something_will_ya!(e) }
|
94
91
|
redis: {
|
95
92
|
# ... redis options ...
|
96
93
|
}
|
97
|
-
}
|
98
94
|
```
|
99
95
|
|
100
96
|
**Note** The session will *always* be destroyed when it cannot be loaded.
|
101
97
|
|
102
98
|
### Other notes
|
103
99
|
|
104
|
-
It returns with_indifferent_access if ActiveSupport is defined
|
100
|
+
It returns with_indifferent_access if ActiveSupport is defined.
|
105
101
|
|
106
102
|
## Rails 2 Compatibility
|
107
103
|
|
data/lib/redis-session-store.rb
CHANGED
@@ -3,7 +3,7 @@ require 'redis'
|
|
3
3
|
# Redis session storage for Rails, and for Rails only. Derived from
|
4
4
|
# the MemCacheStore code, simply dropping in Redis instead.
|
5
5
|
class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
6
|
-
VERSION = '0.11.
|
6
|
+
VERSION = '0.11.6'.freeze
|
7
7
|
# Rails 3.1 and beyond defines the constant elsewhere
|
8
8
|
unless defined?(ENV_SESSION_OPTIONS_KEY)
|
9
9
|
ENV_SESSION_OPTIONS_KEY = if Rack.release.split('.').first.to_i > 1
|
@@ -27,25 +27,23 @@ class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
|
27
27
|
#
|
28
28
|
# ==== Examples
|
29
29
|
#
|
30
|
-
# Rails.application.config.session_store :redis_session_store,
|
30
|
+
# Rails.application.config.session_store :redis_session_store,
|
31
31
|
# key: 'your_session_key',
|
32
32
|
# redis: {
|
33
33
|
# expire_after: 120.minutes,
|
34
34
|
# key_prefix: 'myapp:session:',
|
35
35
|
# url: 'redis://localhost:6379/0'
|
36
36
|
# },
|
37
|
-
# on_redis_down: ->(*a) { logger.error("Redis down! #{a.inspect}") }
|
37
|
+
# on_redis_down: ->(*a) { logger.error("Redis down! #{a.inspect}") },
|
38
38
|
# serializer: :hybrid # migrate from Marshal to JSON
|
39
|
-
# }
|
40
39
|
#
|
41
40
|
def initialize(app, options = {})
|
42
41
|
super
|
43
42
|
|
44
|
-
redis_options = options[:redis] || {}
|
45
|
-
|
46
43
|
@default_options[:namespace] = 'rack:session'
|
47
|
-
@default_options.merge!(
|
48
|
-
|
44
|
+
@default_options.merge!(options[:redis] || {})
|
45
|
+
init_options = options[:redis]&.reject { |k, _v| %i[expire_after key_prefix].include?(k) } || {}
|
46
|
+
@redis = init_options[:client] || Redis.new(init_options)
|
49
47
|
@on_redis_down = options[:on_redis_down]
|
50
48
|
@serializer = determine_serializer(options[:serializer])
|
51
49
|
@on_session_load_error = options[:on_session_load_error]
|
@@ -67,7 +65,7 @@ class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
|
67
65
|
|
68
66
|
!!(
|
69
67
|
value && !value.empty? &&
|
70
|
-
|
68
|
+
key_exists_with_fallback?(value)
|
71
69
|
)
|
72
70
|
rescue Errno::ECONNREFUSED, Redis::CannotConnectError => e
|
73
71
|
on_redis_down.call(e, env, value) if on_redis_down
|
@@ -75,6 +73,12 @@ class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
|
75
73
|
true
|
76
74
|
end
|
77
75
|
|
76
|
+
def key_exists_with_fallback?(value)
|
77
|
+
return false if private_session_id?(value.public_id)
|
78
|
+
|
79
|
+
key_exists?(value.private_id) || key_exists?(value.public_id)
|
80
|
+
end
|
81
|
+
|
78
82
|
def key_exists?(value)
|
79
83
|
if redis.respond_to?(:exists?)
|
80
84
|
# added in redis gem v4.2
|
@@ -85,6 +89,10 @@ class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
92
|
+
def private_session_id?(value)
|
93
|
+
value.match?(/\A\d+::/)
|
94
|
+
end
|
95
|
+
|
88
96
|
def verify_handlers!
|
89
97
|
%w(on_redis_down on_session_load_error).each do |h|
|
90
98
|
next unless (handler = public_send(h)) && !handler.respond_to?(:call)
|
@@ -102,13 +110,21 @@ class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
|
102
110
|
end
|
103
111
|
|
104
112
|
def get_session(env, sid)
|
105
|
-
sid && (session =
|
113
|
+
sid && (session = load_session_with_fallback(sid)) ? [sid, session] : session_default_values
|
106
114
|
rescue Errno::ECONNREFUSED, Redis::CannotConnectError => e
|
107
115
|
on_redis_down.call(e, env, sid) if on_redis_down
|
108
116
|
session_default_values
|
109
117
|
end
|
110
118
|
alias find_session get_session
|
111
119
|
|
120
|
+
def load_session_with_fallback(sid)
|
121
|
+
return nil if private_session_id?(sid.public_id)
|
122
|
+
|
123
|
+
load_session_from_redis(
|
124
|
+
key_exists?(sid.private_id) ? sid.private_id : sid.public_id
|
125
|
+
)
|
126
|
+
end
|
127
|
+
|
112
128
|
def load_session_from_redis(sid)
|
113
129
|
data = redis.get(prefixed(sid))
|
114
130
|
begin
|
@@ -128,9 +144,9 @@ class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
|
128
144
|
def set_session(env, sid, session_data, options = nil)
|
129
145
|
expiry = get_expiry(env, options)
|
130
146
|
if expiry
|
131
|
-
redis.setex(prefixed(sid), expiry, encode(session_data))
|
147
|
+
redis.setex(prefixed(sid.private_id), expiry, encode(session_data))
|
132
148
|
else
|
133
|
-
redis.set(prefixed(sid), encode(session_data))
|
149
|
+
redis.set(prefixed(sid.private_id), encode(session_data))
|
134
150
|
end
|
135
151
|
sid
|
136
152
|
rescue Errno::ECONNREFUSED, Redis::CannotConnectError => e
|
@@ -149,14 +165,17 @@ class RedisSessionStore < ActionDispatch::Session::AbstractSecureStore
|
|
149
165
|
end
|
150
166
|
|
151
167
|
def destroy_session(env, sid, options)
|
152
|
-
destroy_session_from_sid(sid, (options || {}).to_hash.merge(env: env))
|
168
|
+
destroy_session_from_sid(sid.public_id, (options || {}).to_hash.merge(env: env, drop: true))
|
169
|
+
destroy_session_from_sid(sid.private_id, (options || {}).to_hash.merge(env: env))
|
153
170
|
end
|
154
171
|
alias delete_session destroy_session
|
155
172
|
|
156
173
|
def destroy(env)
|
157
174
|
if env['rack.request.cookie_hash'] &&
|
158
175
|
(sid = env['rack.request.cookie_hash'][key])
|
159
|
-
|
176
|
+
sid = Rack::Session::SessionId.new(sid)
|
177
|
+
destroy_session_from_sid(sid.private_id, drop: true, env: env)
|
178
|
+
destroy_session_from_sid(sid.public_id, drop: true, env: env)
|
160
179
|
end
|
161
180
|
false
|
162
181
|
end
|
data/redis-session-store.gemspec
CHANGED
@@ -15,8 +15,8 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.version = File.read('lib/redis-session-store.rb')
|
16
16
|
.match(/^ VERSION = '(.*)'/)[1]
|
17
17
|
|
18
|
-
gem.add_runtime_dependency 'actionpack', '>=
|
19
|
-
gem.add_runtime_dependency 'redis', '>= 3', '<
|
18
|
+
gem.add_runtime_dependency 'actionpack', '>= 5.2.4.1', '< 9'
|
19
|
+
gem.add_runtime_dependency 'redis', '>= 3', '< 6'
|
20
20
|
|
21
21
|
gem.add_development_dependency 'fakeredis', '~> 0.8'
|
22
22
|
gem.add_development_dependency 'rake', '~> 13'
|
@@ -157,7 +157,7 @@ describe RedisSessionStore do
|
|
157
157
|
# https://github.com/rack/rack/blob/1.4.5/lib/rack/session/abstract/id.rb
|
158
158
|
|
159
159
|
let(:env) { double('env') }
|
160
|
-
let(:session_id) {
|
160
|
+
let(:session_id) { Rack::Session::SessionId.new('12 345') }
|
161
161
|
let(:session_data) { double('session_data') }
|
162
162
|
let(:options) { { expire_after: 123 } }
|
163
163
|
|
@@ -217,7 +217,8 @@ describe RedisSessionStore do
|
|
217
217
|
end
|
218
218
|
|
219
219
|
describe 'checking for session existence' do
|
220
|
-
let(:
|
220
|
+
let(:public_id) { 'foo' }
|
221
|
+
let(:session_id) { Rack::Session::SessionId.new(public_id) }
|
221
222
|
|
222
223
|
before do
|
223
224
|
allow(store).to receive(:current_session_id)
|
@@ -234,10 +235,9 @@ describe RedisSessionStore do
|
|
234
235
|
end
|
235
236
|
|
236
237
|
context 'when session id is empty string' do
|
237
|
-
let(:
|
238
|
+
let(:public_id) { '' }
|
238
239
|
|
239
240
|
it 'returns false' do
|
240
|
-
allow(store).to receive(:current_session_id).with(:env).and_return('')
|
241
241
|
expect(store.send(:session_exists?, :env)).to eq(false)
|
242
242
|
end
|
243
243
|
end
|
@@ -250,20 +250,46 @@ describe RedisSessionStore do
|
|
250
250
|
end
|
251
251
|
end
|
252
252
|
|
253
|
-
context 'when session id does not exist in redis' do
|
254
|
-
|
255
|
-
|
256
|
-
|
253
|
+
context 'when session private id does not exist in redis' do
|
254
|
+
context 'when session public id does not exist in redis' do
|
255
|
+
it 'returns false' do
|
256
|
+
expect(redis).to receive(:exists)
|
257
|
+
.with(session_id.private_id)
|
258
|
+
.and_return(false)
|
259
|
+
expect(redis).to receive(:exists).with('foo').and_return(false)
|
260
|
+
expect(store.send(:session_exists?, :env)).to eq(false)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context 'when session public id exists in redis' do
|
265
|
+
it 'returns true' do
|
266
|
+
expect(redis).to receive(:exists)
|
267
|
+
.with(session_id.private_id)
|
268
|
+
.and_return(false)
|
269
|
+
expect(redis).to receive(:exists).with('foo').and_return(true)
|
270
|
+
expect(store.send(:session_exists?, :env)).to eq(true)
|
271
|
+
end
|
257
272
|
end
|
258
273
|
end
|
259
274
|
|
260
|
-
context 'when session id exists in redis' do
|
275
|
+
context 'when session private id exists in redis' do
|
261
276
|
it 'returns true' do
|
262
|
-
expect(redis).to receive(:exists)
|
277
|
+
expect(redis).to receive(:exists)
|
278
|
+
.with(session_id.private_id)
|
279
|
+
.and_return(true)
|
263
280
|
expect(store.send(:session_exists?, :env)).to eq(true)
|
264
281
|
end
|
265
282
|
end
|
266
283
|
|
284
|
+
context 'when session public id is formatted like a private id' do
|
285
|
+
let(:public_id) { Rack::Session::SessionId.new('foo').private_id }
|
286
|
+
|
287
|
+
it 'returns false' do
|
288
|
+
expect(redis).not_to receive(:exists)
|
289
|
+
expect(store.send(:session_exists?, :env)).to eq(false)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
267
293
|
context 'when redis is down' do
|
268
294
|
it 'returns true (fallback to old behavior)' do
|
269
295
|
allow(store).to receive(:redis).and_raise(Redis::CannotConnectError)
|
@@ -281,6 +307,7 @@ describe RedisSessionStore do
|
|
281
307
|
end
|
282
308
|
|
283
309
|
let(:fake_key) { 'thisisarediskey' }
|
310
|
+
let(:session_id) { Rack::Session::SessionId.new(fake_key) }
|
284
311
|
|
285
312
|
describe 'generate_sid' do
|
286
313
|
it 'generates a secure ID' do
|
@@ -289,13 +316,50 @@ describe RedisSessionStore do
|
|
289
316
|
end
|
290
317
|
end
|
291
318
|
|
292
|
-
|
293
|
-
redis
|
294
|
-
|
295
|
-
|
296
|
-
|
319
|
+
context 'when redis is up' do
|
320
|
+
let(:redis) { double('redis') }
|
321
|
+
let(:private_exists) { true }
|
322
|
+
|
323
|
+
before do
|
324
|
+
allow(store).to receive(:redis).and_return(redis)
|
325
|
+
allow(redis).to receive(:exists)
|
326
|
+
.with("#{options[:key_prefix]}#{session_id.private_id}")
|
327
|
+
.and_return(private_exists)
|
328
|
+
end
|
297
329
|
|
298
|
-
|
330
|
+
context 'when session private id exists in redis' do
|
331
|
+
it 'retrieves the prefixed private id from redis' do
|
332
|
+
expect(redis).to receive(:get).with("#{options[:key_prefix]}#{session_id.private_id}")
|
333
|
+
|
334
|
+
store.send(:get_session, double('env'), session_id)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
context 'when session private id not found in redis' do
|
339
|
+
let(:private_exists) { false }
|
340
|
+
|
341
|
+
it 'retrieves the prefixed public id from redis' do
|
342
|
+
expect(redis).to receive(:get).with("#{options[:key_prefix]}#{fake_key}")
|
343
|
+
|
344
|
+
store.send(:get_session, double('env'), session_id)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
context 'when session id is formatted like a private id' do
|
349
|
+
let(:fake_key) { Rack::Session::SessionId.new('anykey').private_id }
|
350
|
+
let(:new_sid) { Rack::Session::SessionId.new('newid') }
|
351
|
+
|
352
|
+
before do
|
353
|
+
allow(store).to receive(:generate_sid).and_return(new_sid)
|
354
|
+
end
|
355
|
+
|
356
|
+
it 'returns a default new session' do
|
357
|
+
expect(redis).not_to receive(:exists)
|
358
|
+
expect(redis).not_to receive(:get)
|
359
|
+
expect(store.send(:get_session, double('env'), session_id))
|
360
|
+
.to eq([new_sid, {}])
|
361
|
+
end
|
362
|
+
end
|
299
363
|
end
|
300
364
|
|
301
365
|
context 'when redis is down' do
|
@@ -305,12 +369,12 @@ describe RedisSessionStore do
|
|
305
369
|
end
|
306
370
|
|
307
371
|
it 'returns an empty session hash' do
|
308
|
-
expect(store.send(:get_session, double('env'),
|
372
|
+
expect(store.send(:get_session, double('env'), session_id).last)
|
309
373
|
.to eq({})
|
310
374
|
end
|
311
375
|
|
312
376
|
it 'returns a newly generated sid' do
|
313
|
-
expect(store.send(:get_session, double('env'),
|
377
|
+
expect(store.send(:get_session, double('env'), session_id).first)
|
314
378
|
.to eq('foop')
|
315
379
|
end
|
316
380
|
|
@@ -319,7 +383,7 @@ describe RedisSessionStore do
|
|
319
383
|
|
320
384
|
it 'explodes' do
|
321
385
|
expect do
|
322
|
-
store.send(:get_session, double('env'),
|
386
|
+
store.send(:get_session, double('env'), session_id)
|
323
387
|
end.to raise_error(Redis::CannotConnectError)
|
324
388
|
end
|
325
389
|
end
|
@@ -331,6 +395,7 @@ describe RedisSessionStore do
|
|
331
395
|
let(:env) { { 'rack.request.cookie_hash' => cookie_hash } }
|
332
396
|
let(:cookie_hash) { double('cookie hash') }
|
333
397
|
let(:fake_key) { 'thisisarediskey' }
|
398
|
+
let(:session_id) { Rack::Session::SessionId.new(fake_key) }
|
334
399
|
|
335
400
|
before do
|
336
401
|
allow(cookie_hash).to receive(:[]).and_return(fake_key)
|
@@ -341,6 +406,8 @@ describe RedisSessionStore do
|
|
341
406
|
allow(store).to receive(:redis).and_return(redis)
|
342
407
|
expect(redis).to receive(:del)
|
343
408
|
.with("#{options[:key_prefix]}#{fake_key}")
|
409
|
+
expect(redis).to receive(:del)
|
410
|
+
.with("#{options[:key_prefix]}#{session_id.private_id}")
|
344
411
|
|
345
412
|
store.send(:destroy, env)
|
346
413
|
end
|
@@ -371,7 +438,8 @@ describe RedisSessionStore do
|
|
371
438
|
redis = double('redis', setnx: true)
|
372
439
|
allow(store).to receive(:redis).and_return(redis)
|
373
440
|
sid = store.send(:generate_sid)
|
374
|
-
expect(redis).to receive(:del).with("#{options[:key_prefix]}#{sid}")
|
441
|
+
expect(redis).to receive(:del).with("#{options[:key_prefix]}#{sid.public_id}")
|
442
|
+
expect(redis).to receive(:del).with("#{options[:key_prefix]}#{sid.private_id}")
|
375
443
|
|
376
444
|
store.send(:destroy_session, {}, sid, nil)
|
377
445
|
end
|
@@ -380,7 +448,7 @@ describe RedisSessionStore do
|
|
380
448
|
|
381
449
|
describe 'session encoding' do
|
382
450
|
let(:env) { double('env') }
|
383
|
-
let(:session_id) {
|
451
|
+
let(:session_id) { Rack::Session::SessionId.new('12 345') }
|
384
452
|
let(:session_data) { { 'some' => 'data' } }
|
385
453
|
let(:options) { {} }
|
386
454
|
let(:encoded_data) { Marshal.dump(session_data) }
|
@@ -393,11 +461,12 @@ describe RedisSessionStore do
|
|
393
461
|
|
394
462
|
shared_examples_for 'serializer' do
|
395
463
|
it 'encodes correctly' do
|
396
|
-
expect(redis).to receive(:set).with(
|
464
|
+
expect(redis).to receive(:set).with(session_id.private_id, expected_encoding)
|
397
465
|
store.send(:set_session, env, session_id, session_data, options)
|
398
466
|
end
|
399
467
|
|
400
468
|
it 'decodes correctly' do
|
469
|
+
allow(redis).to receive(:exists).with(session_id.private_id).and_return(true)
|
401
470
|
expect(store.send(:get_session, env, session_id))
|
402
471
|
.to eq([session_id, session_data])
|
403
472
|
end
|
@@ -548,7 +617,7 @@ describe RedisSessionStore do
|
|
548
617
|
describe 'setting the session' do
|
549
618
|
it 'allows changing the session' do
|
550
619
|
env = { 'rack.session.options' => {} }
|
551
|
-
sid = 1234
|
620
|
+
sid = Rack::Session::SessionId.new('1234')
|
552
621
|
allow(store).to receive(:redis).and_return(Redis.new)
|
553
622
|
data1 = { 'foo' => 'bar' }
|
554
623
|
store.send(:set_session, env, sid, data1)
|
@@ -560,7 +629,7 @@ describe RedisSessionStore do
|
|
560
629
|
|
561
630
|
it 'allows changing the session when the session has an expiry' do
|
562
631
|
env = { 'rack.session.options' => { expire_after: 60 } }
|
563
|
-
sid = 1234
|
632
|
+
sid = Rack::Session::SessionId.new('1234')
|
564
633
|
allow(store).to receive(:redis).and_return(Redis.new)
|
565
634
|
data1 = { 'foo' => 'bar' }
|
566
635
|
store.send(:set_session, env, sid, data1)
|
data/spec/support.rb
CHANGED
@@ -11,10 +11,32 @@ unless defined?(Rack::Session::SessionId)
|
|
11
11
|
module Rack
|
12
12
|
module Session
|
13
13
|
class SessionId
|
14
|
+
ID_VERSION = 2
|
15
|
+
|
14
16
|
attr_reader :public_id
|
15
17
|
|
16
|
-
def initialize(
|
17
|
-
@public_id
|
18
|
+
def initialize(public_id)
|
19
|
+
@public_id = public_id
|
20
|
+
end
|
21
|
+
|
22
|
+
alias to_s public_id
|
23
|
+
|
24
|
+
def empty?
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
def inspect
|
29
|
+
public_id.inspect
|
30
|
+
end
|
31
|
+
|
32
|
+
def private_id
|
33
|
+
"#{ID_VERSION}::#{hash_sid(public_id)}"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def hash_sid(value)
|
39
|
+
"test_hash_from:#{value}"
|
18
40
|
end
|
19
41
|
end
|
20
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-session-store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.11.
|
4
|
+
version: 0.11.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mathias Meyer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.2.4.1
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '9'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: 5.2.4.1
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '9'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: redis
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: '3'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '6'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: '3'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '6'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: fakeredis
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -197,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
197
|
- !ruby/object:Gem::Version
|
198
198
|
version: '0'
|
199
199
|
requirements: []
|
200
|
-
rubygems_version: 3.
|
200
|
+
rubygems_version: 3.5.23
|
201
201
|
signing_key:
|
202
202
|
specification_version: 4
|
203
203
|
summary: A drop-in replacement for e.g. MemCacheStore to store Rails sessions (and
|