multi_session_store 0.1.0 → 0.2.5

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 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