multi_session_store 0.1.0 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b649eeeeb5c3a7664b5150d21a3298b1e6aa01f6a12acfff10d948decd446a9
4
- data.tar.gz: 72de55c4116b17e9adfd9af8d182b9fae01614d4a8eeb367665bd54790ee28cd
3
+ metadata.gz: 3901d210eb5e3f7b8bc360475fbff5aebe3f3e3dffcd9d1e5e3f617eacb8f51a
4
+ data.tar.gz: edf3697da991dfc54201a2ddbd42bb1c5d23aea1f0d195de6c59c841ae74edfe
5
5
  SHA512:
6
- metadata.gz: 8ce98ad8fa45122300bd79569dee41e0d491b39b0626ee315adccc8018bf77336766f0e0fa1b9b69701c4d5e9c0a5bed913ff4b58b1fe309c5ba16cb438e1ab5
7
- data.tar.gz: 9bfe13213d26b635ca339566b73ea11c5b6c7cb951716867dd74d8a9cdbb0cdacd4909bcefb35d0ccb7e12a63f87e8b0f9b8b59473f1a9d3037ea602d5c5eeda
6
+ metadata.gz: bb5c11d4cb0b2e0e43351bdad10b7fc9201149d78011a6873f0430ba663f33cd707433539e1fe9c5b64674f381dad509c6e9a56016fdd1af7166aab98efad430
7
+ data.tar.gz: b9842a6bacdc0663a540ea04e4e4027ff690ccc5e009eab95002104c479a2c836fc9f9cbc0aacfa198d28b1c3a314a336d5aa3e253945d7b62c95df53730ce5e
data/.gitignore CHANGED
@@ -10,3 +10,4 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
  /Gemfile.lock
13
+ .ruby-version
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "multi/session/store"
4
+ require "multi_session_store"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -1,49 +1,75 @@
1
1
  require "multi_session_store/version"
2
+ require "multi_session_store/subsession_generator_middleware"
3
+ require "multi_session_store/default_url_options"
4
+ require "multi_session_store/railtie" if defined? Rails
2
5
  require "action_dispatch"
6
+ require 'json'
3
7
 
4
8
  module ActionDispatch
5
9
  module Session
6
10
  class MultiSessionStore < AbstractStore
11
+ DEFAULT_SESSION_EXPIRATION = 24 * 60 * 60
12
+ DEFAULT_PARAM_NAME = 'subsession_id'.freeze
13
+
7
14
  def initialize(app, options = {})
8
- @cache = options[:cache]
9
- options[:expire_after] ||= @cache.options[:expires_in]
10
- @param = options[:param]
15
+ options[:expire_after] ||= DEFAULT_SESSION_EXPIRATION
16
+ options[:param_name] ||= DEFAULT_PARAM_NAME
17
+ options[:serializer] ||= JSON
18
+ @redis = options[:redis]
19
+ @param_name = options[:param_name]
11
20
  @serializer = options[:serializer]
12
-
13
21
  super
14
22
  end
15
23
 
16
24
  def find_session(env, sid)
17
- sid ||= generate_sid
18
- session = @serializer.parse(@cache.read(cache_key(env, sid)) || "{}")
19
-
20
- [sid, session]
25
+ if sid
26
+ serialized_session_data = @redis.get session_store_key(env, sid)
27
+ session_data = serialized_session_data ? @serializer.parse(serialized_session_data) : {}
28
+ [sid, session_data]
29
+ else
30
+ [generate_sid, {}]
31
+ end
21
32
  end
22
33
 
23
34
  def write_session(env, sid, session, options)
24
- key = cache_key(env, sid)
25
-
35
+ key = session_store_key env, sid
26
36
  if session
27
- @cache.write(key, @serializer.dump(session), expires_in: options[:expire_after])
37
+ @redis.set key, @serializer.dump(session), ex: options[:expire_after]
28
38
  else
29
- @cache.delete(key)
39
+ @redis.del key
30
40
  end
31
-
32
41
  sid
33
42
  end
34
43
 
35
44
  def delete_session(env, sid, options)
36
- @cache.delete(cache_key(env, sid))
37
-
45
+ @redis.del session_store_key(env, sid)
38
46
  sid
39
47
  end
40
48
 
41
- private
49
+ def validate_sessions(&block)
50
+ all_sessions.each do |key, session|
51
+ @redis.del key unless block.call session
52
+ end
53
+ end
42
54
 
43
- def cache_key(env, sid)
44
- subsession_id = env.params[@param] || "no_subsession"
55
+ private
56
+
57
+ def session_store_key(env, sid)
58
+ subsession_id = env.params[@param_name] || 'no_subsession'
45
59
  "_session_id:#{sid}:#{subsession_id}"
46
60
  end
61
+
62
+ def all_sessions
63
+ session_store_keys.each_with_object({}) do |key, memo|
64
+ serialized_value = @redis.get key
65
+ next if serialized_value.nil?
66
+ memo[key] = @serializer.parse serialized_value
67
+ end
68
+ end
69
+
70
+ def session_store_keys
71
+ @redis.keys "_session_id:*"
72
+ end
47
73
  end
48
74
  end
49
75
  end
@@ -0,0 +1,12 @@
1
+ module MultiSessionStore
2
+ module DefaultUrlOptions
3
+ def default_url_options
4
+ options = params[:subsession_id] ? {subsession_id: params[:subsession_id]} : {}
5
+ begin
6
+ super.merge options
7
+ rescue NoMethodError
8
+ options
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ module MultiSessionStore
2
+ class Railtie < Rails::Railtie
3
+ config.multi_session_store = ActiveSupport::OrderedOptions.new
4
+
5
+ initializer 'multi_session_store.add_middleware' do |app|
6
+ app.config.middleware.insert_before ActionDispatch::Session::MultiSessionStore,
7
+ MultiSessionStore::SubsessionGeneratorMiddleware,
8
+ exclude_paths: app.config.multi_session_store.exclude_paths
9
+ end
10
+
11
+ config.to_prepare do
12
+ ApplicationController.prepend MultiSessionStore::DefaultUrlOptions unless ApplicationController.ancestors.include? MultiSessionStore::DefaultUrlOptions
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,45 @@
1
+ require 'securerandom'
2
+
3
+ module MultiSessionStore
4
+ class SubsessionGeneratorMiddleware
5
+ def initialize(app, config = {})
6
+ @app = app
7
+ @config = config
8
+ end
9
+
10
+ def call(env)
11
+ request = Rack::Request.new(env)
12
+ set_subsession_id_from_header(request)
13
+ generate_subsession_id_if_needed(request)
14
+ @app.call(env)
15
+ end
16
+
17
+ private
18
+
19
+ SUBSESSION_ID_HEADER = 'HTTP_X_SUBSESSIONID'.freeze
20
+
21
+ def set_subsession_id_from_header(request)
22
+ request.update_param 'subsession_id', request.get_header(SUBSESSION_ID_HEADER) if request.has_header?(SUBSESSION_ID_HEADER)
23
+ end
24
+
25
+ def generate_subsession_id_if_needed(request)
26
+ request.update_param 'subsession_id', new_subsession_id if subsession_id_is_needed?(request)
27
+ end
28
+
29
+ def new_subsession_id
30
+ SecureRandom.hex
31
+ end
32
+
33
+ def subsession_id_is_needed?(request)
34
+ !request.params['subsession_id'] && !path_excluded?(request.path)
35
+ end
36
+
37
+ def path_excluded?(current_path)
38
+ excluded_paths.any? { |excluded_path| excluded_path.match? current_path }
39
+ end
40
+
41
+ def excluded_paths
42
+ @config[:exclude_paths] ||= []
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  module MultiSessionStore
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.5"
3
3
  end
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency "bundler", "~> 2.0"
32
32
  spec.add_development_dependency "rake", "~> 10.0"
33
33
  spec.add_development_dependency "rspec", "~> 3.0"
34
- spec.add_development_dependency "pry"
34
+ spec.add_development_dependency "redis", "~> 4.0"
35
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_session_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emarsys Smart Insight developers
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-14 00:00:00.000000000 Z
11
+ date: 2020-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -67,19 +67,19 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: pry
70
+ name: redis
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: '4.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: '4.0'
83
83
  description: This gem provides a means to support multiple sessions across different
84
84
  tabs in the same browser window.
85
85
  email:
@@ -98,6 +98,9 @@ files:
98
98
  - bin/console
99
99
  - bin/setup
100
100
  - lib/multi_session_store.rb
101
+ - lib/multi_session_store/default_url_options.rb
102
+ - lib/multi_session_store/railtie.rb
103
+ - lib/multi_session_store/subsession_generator_middleware.rb
101
104
  - lib/multi_session_store/version.rb
102
105
  - multi_session_store.gemspec
103
106
  homepage: https://github.com/emartech/multi_session_store