mongo_session_store-rails3 3.0.1
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.
- data/.gitignore +6 -0
- data/Gemfile +32 -0
- data/README.md +128 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/lib/mongo_session_store-rails3.rb +32 -0
- data/lib/mongo_session_store/mongo_mapper_store.rb +20 -0
- data/lib/mongo_session_store/mongo_store.rb +80 -0
- data/lib/mongo_session_store/mongo_store_base.rb +77 -0
- data/lib/mongo_session_store/mongoid_store.rb +34 -0
- data/mongo_session_store-rails3.gemspec +16 -0
- data/perf/benchmark.rb +93 -0
- data/spec/integration_with_devise_spec.rb +84 -0
- data/spec/rails_3.0_app/.gitignore +4 -0
- data/spec/rails_3.0_app/README +256 -0
- data/spec/rails_3.0_app/Rakefile +7 -0
- data/spec/rails_3.0_app/app/controllers/application_controller.rb +3 -0
- data/spec/rails_3.0_app/app/controllers/home_controller.rb +4 -0
- data/spec/rails_3.0_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_3.0_app/app/models/user.rb +8 -0
- data/spec/rails_3.0_app/app/views/devise/confirmations/new.html.erb +12 -0
- data/spec/rails_3.0_app/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/spec/rails_3.0_app/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
- data/spec/rails_3.0_app/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/spec/rails_3.0_app/app/views/devise/passwords/edit.html.erb +16 -0
- data/spec/rails_3.0_app/app/views/devise/passwords/new.html.erb +12 -0
- data/spec/rails_3.0_app/app/views/devise/registrations/edit.html.erb +25 -0
- data/spec/rails_3.0_app/app/views/devise/registrations/new.html.erb +18 -0
- data/spec/rails_3.0_app/app/views/devise/sessions/new.html.erb +17 -0
- data/spec/rails_3.0_app/app/views/devise/shared/_links.erb +25 -0
- data/spec/rails_3.0_app/app/views/devise/unlocks/new.html.erb +12 -0
- data/spec/rails_3.0_app/app/views/home/index.html.erb +10 -0
- data/spec/rails_3.0_app/app/views/layouts/application.html.erb +15 -0
- data/spec/rails_3.0_app/config.ru +4 -0
- data/spec/rails_3.0_app/config/application.rb +47 -0
- data/spec/rails_3.0_app/config/boot.rb +6 -0
- data/spec/rails_3.0_app/config/environment.rb +5 -0
- data/spec/rails_3.0_app/config/environments/development.rb +26 -0
- data/spec/rails_3.0_app/config/environments/production.rb +49 -0
- data/spec/rails_3.0_app/config/environments/test.rb +35 -0
- data/spec/rails_3.0_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_3.0_app/config/initializers/devise.rb +204 -0
- data/spec/rails_3.0_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_3.0_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_3.0_app/config/initializers/secret_token.rb +7 -0
- data/spec/rails_3.0_app/config/initializers/session_store.rb +8 -0
- data/spec/rails_3.0_app/config/locales/devise.en.yml +53 -0
- data/spec/rails_3.0_app/config/locales/en.yml +5 -0
- data/spec/rails_3.0_app/config/mongo.yml +18 -0
- data/spec/rails_3.0_app/config/mongoid.yml +20 -0
- data/spec/rails_3.0_app/config/routes.rb +4 -0
- data/spec/rails_3.0_app/lib/tasks/.gitkeep +0 -0
- data/spec/rails_3.0_app/public/404.html +26 -0
- data/spec/rails_3.0_app/public/422.html +26 -0
- data/spec/rails_3.0_app/public/500.html +26 -0
- data/spec/rails_3.0_app/public/favicon.ico +0 -0
- data/spec/rails_3.0_app/public/javascripts/.gitkeep +0 -0
- data/spec/rails_3.0_app/public/javascripts/application.js +0 -0
- data/spec/rails_3.0_app/public/robots.txt +5 -0
- data/spec/rails_3.0_app/public/stylesheets/.gitkeep +0 -0
- data/spec/rails_3.0_app/script/rails +6 -0
- data/spec/rails_3.0_app/vendor/plugins/.gitkeep +0 -0
- data/spec/rails_3.1_app/.gitignore +5 -0
- data/spec/rails_3.1_app/README +261 -0
- data/spec/rails_3.1_app/Rakefile +7 -0
- data/spec/rails_3.1_app/app/assets/javascripts/application.js +7 -0
- data/spec/rails_3.1_app/app/assets/stylesheets/application.css +7 -0
- data/spec/rails_3.1_app/app/controllers/application_controller.rb +3 -0
- data/spec/rails_3.1_app/app/controllers/home_controller.rb +4 -0
- data/spec/rails_3.1_app/app/helpers/application_helper.rb +2 -0
- data/spec/rails_3.1_app/app/mailers/.gitkeep +0 -0
- data/spec/rails_3.1_app/app/models/.gitkeep +0 -0
- data/spec/rails_3.1_app/app/models/user.rb +8 -0
- data/spec/rails_3.1_app/app/views/devise/confirmations/new.html.erb +12 -0
- data/spec/rails_3.1_app/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
- data/spec/rails_3.1_app/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
- data/spec/rails_3.1_app/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
- data/spec/rails_3.1_app/app/views/devise/passwords/edit.html.erb +16 -0
- data/spec/rails_3.1_app/app/views/devise/passwords/new.html.erb +12 -0
- data/spec/rails_3.1_app/app/views/devise/registrations/edit.html.erb +25 -0
- data/spec/rails_3.1_app/app/views/devise/registrations/new.html.erb +18 -0
- data/spec/rails_3.1_app/app/views/devise/sessions/new.html.erb +17 -0
- data/spec/rails_3.1_app/app/views/devise/shared/_links.erb +25 -0
- data/spec/rails_3.1_app/app/views/devise/unlocks/new.html.erb +12 -0
- data/spec/rails_3.1_app/app/views/home/index.html.erb +10 -0
- data/spec/rails_3.1_app/app/views/layouts/application.html.erb +15 -0
- data/spec/rails_3.1_app/config.ru +4 -0
- data/spec/rails_3.1_app/config/application.rb +47 -0
- data/spec/rails_3.1_app/config/boot.rb +6 -0
- data/spec/rails_3.1_app/config/environment.rb +5 -0
- data/spec/rails_3.1_app/config/environments/development.rb +27 -0
- data/spec/rails_3.1_app/config/environments/production.rb +54 -0
- data/spec/rails_3.1_app/config/environments/test.rb +39 -0
- data/spec/rails_3.1_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/rails_3.1_app/config/initializers/devise.rb +204 -0
- data/spec/rails_3.1_app/config/initializers/inflections.rb +10 -0
- data/spec/rails_3.1_app/config/initializers/mime_types.rb +5 -0
- data/spec/rails_3.1_app/config/initializers/secret_token.rb +7 -0
- data/spec/rails_3.1_app/config/initializers/session_store.rb +8 -0
- data/spec/rails_3.1_app/config/initializers/wrap_parameters.rb +12 -0
- data/spec/rails_3.1_app/config/locales/devise.en.yml +53 -0
- data/spec/rails_3.1_app/config/locales/en.yml +5 -0
- data/spec/rails_3.1_app/config/mongo.yml +18 -0
- data/spec/rails_3.1_app/config/mongoid.yml +20 -0
- data/spec/rails_3.1_app/config/routes.rb +4 -0
- data/spec/rails_3.1_app/lib/tasks/.gitkeep +0 -0
- data/spec/rails_3.1_app/log/.gitkeep +0 -0
- data/spec/rails_3.1_app/public/404.html +26 -0
- data/spec/rails_3.1_app/public/422.html +26 -0
- data/spec/rails_3.1_app/public/500.html +26 -0
- data/spec/rails_3.1_app/public/favicon.ico +0 -0
- data/spec/rails_3.1_app/public/robots.txt +5 -0
- data/spec/rails_3.1_app/script/rails +6 -0
- data/spec/rails_3.1_app/vendor/assets/stylesheets/.gitkeep +0 -0
- data/spec/rails_3.1_app/vendor/plugins/.gitkeep +0 -0
- data/spec/spec_helper.rb +33 -0
- metadata +318 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
source :rubygems
|
|
2
|
+
|
|
3
|
+
MONGO_VERS = '1.3.1' unless defined? MONGO_VERS
|
|
4
|
+
|
|
5
|
+
RAILS_VERS = case ENV['RAILS_VERS']
|
|
6
|
+
when '3.0'
|
|
7
|
+
'~>3.0'
|
|
8
|
+
when '3.1'
|
|
9
|
+
'>3.1.0.pre'
|
|
10
|
+
when nil
|
|
11
|
+
nil
|
|
12
|
+
else
|
|
13
|
+
raise "Invalid RAILS_VERS. Available versions are 3.0 and 3.1."
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
gemspec
|
|
17
|
+
|
|
18
|
+
group :development, :test do
|
|
19
|
+
gem 'rake'
|
|
20
|
+
gem 'mongo_mapper', '>= 0.9.0'
|
|
21
|
+
gem 'mongoid', '>= 2.0'
|
|
22
|
+
gem 'mongo', MONGO_VERS
|
|
23
|
+
gem 'bson_ext', MONGO_VERS
|
|
24
|
+
|
|
25
|
+
gem 'system_timer', :platforms => :ruby_18
|
|
26
|
+
gem 'ruby-debug', :platforms => :ruby_18
|
|
27
|
+
gem 'ruby-debug19', :platforms => :ruby_19
|
|
28
|
+
|
|
29
|
+
RAILS_VERS ? gem('rails', RAILS_VERS) : gem('rails')
|
|
30
|
+
gem 'rspec-rails'
|
|
31
|
+
gem 'devise'
|
|
32
|
+
end
|
data/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# MongoSessionStore
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
MongoSessionStore is a collection of Rails-compatible session stores for MongoMapper and Mongoid, but also included is a generic Mongo store that works with any (or no!) Mongo ODM.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
MongoSessionStore is compatible with Rails 3.0 and 3.1
|
|
10
|
+
|
|
11
|
+
In your Gemfile:
|
|
12
|
+
|
|
13
|
+
gem "mongo_mapper"
|
|
14
|
+
gem "mongo_session_store-rails3"
|
|
15
|
+
|
|
16
|
+
In the session_store initializer (config/initializers/session_store.rb):
|
|
17
|
+
|
|
18
|
+
# MongoMapper
|
|
19
|
+
MyApp::Application.config.session_store = :mongo_mapper_store
|
|
20
|
+
|
|
21
|
+
# Mongoid
|
|
22
|
+
MyApp::Application.config.session_store = :mongoid_store
|
|
23
|
+
|
|
24
|
+
# anything else
|
|
25
|
+
MyApp::Application.config.session_store = :mongo_store
|
|
26
|
+
ActionDispatch::Session:MongoStore::Session.database = Mongo::Connection.new.db('my_app_development')
|
|
27
|
+
|
|
28
|
+
Note: If you choose to use the :mongo_store you only need to set its database if you aren't using MongoMapper or Mongoid in your project.
|
|
29
|
+
|
|
30
|
+
By default, the sessions will be stored in the "sessions" collection in MongoDB. If you want to use a different collection, you can set that in the initializer:
|
|
31
|
+
|
|
32
|
+
MongoSessionStore.collection_name = "client_sessions"
|
|
33
|
+
|
|
34
|
+
If for some reason you want to query your sessions:
|
|
35
|
+
|
|
36
|
+
# MongoMapper
|
|
37
|
+
ActionDispatch::Session:MongoMapperStore::Session.where(:updated_at.gt => 2.days.ago)
|
|
38
|
+
|
|
39
|
+
# Mongoid
|
|
40
|
+
ActionDispatch::Session:MongoidStore::Session.where(:updated_at.gt => 2.days.ago)
|
|
41
|
+
|
|
42
|
+
# Plain old Mongo
|
|
43
|
+
ActionDispatch::Session:MongoStore::Session.where('updated_at' => { '$gt' => 2.days.ago })
|
|
44
|
+
|
|
45
|
+
## Performance
|
|
46
|
+
|
|
47
|
+
The following is the benchmark run with bson_ext installed. Without bson_ext, speeds are about 10x slower. The benchmark saves 2000 sessions (~12kb each) and then finds/reloads each one.
|
|
48
|
+
|
|
49
|
+
$ ruby perf/benchmark.rb
|
|
50
|
+
MongoMapperStore...
|
|
51
|
+
3.65ms per session save
|
|
52
|
+
2.25ms per session load
|
|
53
|
+
Total Size: 23648924
|
|
54
|
+
Object count: 2000
|
|
55
|
+
Average object size: 11824.462
|
|
56
|
+
Index sizes: {"_id_"=>172032}
|
|
57
|
+
MongoidStore...
|
|
58
|
+
2.59ms per session save
|
|
59
|
+
1.33ms per session load
|
|
60
|
+
Total Size: 23648924
|
|
61
|
+
Object count: 2000
|
|
62
|
+
Average object size: 11824.462
|
|
63
|
+
Index sizes: {"_id_"=>172032}
|
|
64
|
+
MongoStore...
|
|
65
|
+
1.42ms per session save
|
|
66
|
+
1.11ms per session load
|
|
67
|
+
Total Size: 23648924
|
|
68
|
+
Object count: 2000
|
|
69
|
+
Average object size: 11824.462
|
|
70
|
+
Index sizes: {"_id_"=>204800}
|
|
71
|
+
|
|
72
|
+
## Development
|
|
73
|
+
|
|
74
|
+
To run all the tests:
|
|
75
|
+
|
|
76
|
+
rake
|
|
77
|
+
|
|
78
|
+
To switch to the Rails 3.0 Gemfile.lock:
|
|
79
|
+
|
|
80
|
+
rake use_rails_30
|
|
81
|
+
|
|
82
|
+
To switch to the Rails 3.1 Gemfile.lock:
|
|
83
|
+
|
|
84
|
+
rake use_rails_31
|
|
85
|
+
|
|
86
|
+
To run the tests for a specific store:
|
|
87
|
+
|
|
88
|
+
MONGO_SESSION_STORE_ORM=mongo_mapper bundle exec rspec spec
|
|
89
|
+
MONGO_SESSION_STORE_ORM=mongoid bundle exec rspec spec
|
|
90
|
+
|
|
91
|
+
## Previous contributors
|
|
92
|
+
|
|
93
|
+
MongoSessionStore started as a fork of the DataMapper session store, modified to work with MongoMapper and Mongoid. Much thanks to all the previous contributors:
|
|
94
|
+
|
|
95
|
+
* Nicolas Mérouze
|
|
96
|
+
* Chris Brickley
|
|
97
|
+
* Tony Pitale
|
|
98
|
+
* Nicola Racco
|
|
99
|
+
* Matt Powell
|
|
100
|
+
* Ryan Fitzgerald
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
Copyright (c) 2011 Brian Hempel
|
|
105
|
+
Copyright (c) 2010 Nicolas Mérouze
|
|
106
|
+
Copyright (c) 2009 Chris Brickley
|
|
107
|
+
Copyright (c) 2009 Tony Pitale
|
|
108
|
+
|
|
109
|
+
Permission is hereby granted, free of charge, to any person
|
|
110
|
+
obtaining a copy of this software and associated documentation
|
|
111
|
+
files (the "Software"), to deal in the Software without
|
|
112
|
+
restriction, including without limitation the rights to use,
|
|
113
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
114
|
+
copies of the Software, and to permit persons to whom the
|
|
115
|
+
Software is furnished to do so, subject to the following
|
|
116
|
+
conditions:
|
|
117
|
+
|
|
118
|
+
The above copyright notice and this permission notice shall be
|
|
119
|
+
included in all copies or substantial portions of the Software.
|
|
120
|
+
|
|
121
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
122
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
123
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
124
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
125
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
126
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
127
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
128
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'rake'
|
|
3
|
+
|
|
4
|
+
def run_with_output(command)
|
|
5
|
+
puts "Running: #{command}"
|
|
6
|
+
|
|
7
|
+
Process.wait( fork { exec command } )
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def set_rails_version(rails_vers)
|
|
11
|
+
unless File.exists?("Gemfile_Rails_#{rails_vers}.lock")
|
|
12
|
+
run_with_output "export RAILS_VERS=#{rails_vers}; bundle update rails"
|
|
13
|
+
run_with_output "cp Gemfile.lock Gemfile_Rails_#{rails_vers}.lock"
|
|
14
|
+
else
|
|
15
|
+
run_with_output "rm Gemfile.lock"
|
|
16
|
+
run_with_output "cp Gemfile_Rails_#{rails_vers}.lock Gemfile.lock"
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
task :default => :test_all
|
|
21
|
+
|
|
22
|
+
desc 'Test each session store against Rails 3.0 and Rails 3.1'
|
|
23
|
+
task :test_all do
|
|
24
|
+
# inspired by http://pivotallabs.com/users/jdean/blog/articles/1728-testing-your-gem-against-multiple-rubies-and-rails-versions-with-rvm
|
|
25
|
+
|
|
26
|
+
orms = ['mongo_mapper', 'mongoid', 'mongo']
|
|
27
|
+
|
|
28
|
+
set_rails_version('3.0')
|
|
29
|
+
|
|
30
|
+
orms.each do |orm|
|
|
31
|
+
run_with_output "export MONGO_SESSION_STORE_ORM=#{orm}; bundle exec rspec spec"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
set_rails_version('3.1')
|
|
35
|
+
|
|
36
|
+
orms.each do |orm|
|
|
37
|
+
run_with_output "export MONGO_SESSION_STORE_ORM=#{orm}; bundle exec rspec spec"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
desc 'Set Rails version to 3.0'
|
|
42
|
+
task :use_rails_30 do
|
|
43
|
+
set_rails_version('3.0')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
desc 'Set Rails version to 3.1'
|
|
47
|
+
task :use_rails_31 do
|
|
48
|
+
set_rails_version('3.1')
|
|
49
|
+
end
|
data/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.0.1
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'securerandom'
|
|
2
|
+
|
|
3
|
+
$:.unshift File.dirname(__FILE__)
|
|
4
|
+
|
|
5
|
+
module MongoSessionStore
|
|
6
|
+
def self.collection_name=(name)
|
|
7
|
+
@collection_name = name
|
|
8
|
+
|
|
9
|
+
if defined?(ActionDispatch::Session::MongoStore::Session)
|
|
10
|
+
ActionDispatch::Session::MongoStore::Session.reset_collection
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if defined?(ActionDispatch::Session::MongoMapperStore::Session)
|
|
14
|
+
ActionDispatch::Session::MongoMapperStore::Session.set_collection_name(name)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if defined?(ActionDispatch::Session::MongoidStore::Session)
|
|
18
|
+
ActionDispatch::Session::MongoidStore::Session.store_in(name)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.collection_name
|
|
23
|
+
@collection_name
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# default collection name for all the stores
|
|
27
|
+
self.collection_name = "sessions"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
require 'mongo_session_store/mongo_mapper_store'
|
|
31
|
+
require 'mongo_session_store/mongoid_store'
|
|
32
|
+
require 'mongo_session_store/mongo_store'
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'mongo_mapper'
|
|
3
|
+
require 'mongo_session_store/mongo_store_base'
|
|
4
|
+
|
|
5
|
+
module ActionDispatch
|
|
6
|
+
module Session
|
|
7
|
+
class MongoMapperStore < MongoStoreBase
|
|
8
|
+
class Session
|
|
9
|
+
include MongoMapper::Document
|
|
10
|
+
set_collection_name MongoSessionStore.collection_name
|
|
11
|
+
key :_id, String
|
|
12
|
+
key :data, Binary, :default => Marshal.dump({})
|
|
13
|
+
timestamps!
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
rescue LoadError
|
|
20
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'mongo'
|
|
2
|
+
require 'mongo_session_store/mongo_store_base'
|
|
3
|
+
|
|
4
|
+
module ActionDispatch
|
|
5
|
+
module Session
|
|
6
|
+
class MongoStore < MongoStoreBase
|
|
7
|
+
class Session
|
|
8
|
+
attr_accessor :_id, :data, :created_at, :updated_at
|
|
9
|
+
|
|
10
|
+
def initialize(options={})
|
|
11
|
+
@_id = options[:_id]
|
|
12
|
+
@data = options[:data] || BSON::Binary.new(Marshal.dump({}))
|
|
13
|
+
@created_at = options[:created_at]
|
|
14
|
+
@updated_at = options[:updated_at]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.load(options={})
|
|
18
|
+
options[:data] = options["data"].to_s if options["data"]
|
|
19
|
+
new(options)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def destroy
|
|
23
|
+
collection.remove :_id => _id
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def save
|
|
27
|
+
@created_at ||= Time.now
|
|
28
|
+
@updated_at = Time.now
|
|
29
|
+
|
|
30
|
+
collection.save(
|
|
31
|
+
:_id => @_id,
|
|
32
|
+
:data => BSON::Binary.new(@data),
|
|
33
|
+
:created_at => @created_at,
|
|
34
|
+
:updated_at => @updated_at
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def data=(stuff)
|
|
39
|
+
@data = stuff.to_s
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.where(query = {})
|
|
43
|
+
collection.find(query).map { |doc| load(doc) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.last
|
|
47
|
+
where.last
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.database
|
|
51
|
+
if @database
|
|
52
|
+
@database
|
|
53
|
+
elsif defined?(MongoMapper)
|
|
54
|
+
MongoMapper.database
|
|
55
|
+
elsif defined?(Mongoid)
|
|
56
|
+
Mongoid.database
|
|
57
|
+
else
|
|
58
|
+
raise "MongoStore needs a database, e.g. #{name.to_s}.database = Mongo::Connection.new.db('my_app_development')"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.database=(database)
|
|
63
|
+
@database = database
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.collection
|
|
67
|
+
@collection ||= database[MongoSessionStore.collection_name]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def self.reset_collection
|
|
71
|
+
@collection = nil
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def collection
|
|
75
|
+
self.class.collection
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
module ActionDispatch
|
|
2
|
+
module Session
|
|
3
|
+
class MongoStoreBase < AbstractStore
|
|
4
|
+
|
|
5
|
+
SESSION_RECORD_KEY = 'rack.session.record'.freeze
|
|
6
|
+
begin
|
|
7
|
+
ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY
|
|
8
|
+
rescue NameError
|
|
9
|
+
# Rack 1.2.x has access to the ENV_SESSION_OPTIONS_KEY
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.session_class
|
|
13
|
+
self::Session
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
def session_class
|
|
18
|
+
self.class.session_class
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def generate_sid
|
|
22
|
+
# 20 random bytes in url-safe base64
|
|
23
|
+
SecureRandom.base64(20).gsub('=','').gsub('+','-').gsub('/','_')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_session(env, sid)
|
|
27
|
+
sid ||= generate_sid
|
|
28
|
+
session = find_session(sid)
|
|
29
|
+
env[SESSION_RECORD_KEY] = session
|
|
30
|
+
[sid, unpack(session.data)]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def set_session(env, sid, session_data, options = {})
|
|
34
|
+
record = get_session_model(env, sid)
|
|
35
|
+
record.data = pack(session_data)
|
|
36
|
+
# Rack spec dictates that set_session should return true or false
|
|
37
|
+
# depending on whether or not the session was saved or not.
|
|
38
|
+
# However, ActionPack seems to want a session id instead.
|
|
39
|
+
record.save ? sid : false
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def find_session(id)
|
|
43
|
+
session_class.where(:_id => id).first || session_class.new(:_id => id)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def get_session_model(env, sid)
|
|
47
|
+
if env[ENV_SESSION_OPTIONS_KEY][:id].nil?
|
|
48
|
+
env[SESSION_RECORD_KEY] = find_session(sid)
|
|
49
|
+
else
|
|
50
|
+
env[SESSION_RECORD_KEY] ||= find_session(sid)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def destroy_session(env, session_id, options)
|
|
55
|
+
destroy(env)
|
|
56
|
+
generate_sid unless options[:drop]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def destroy(env)
|
|
60
|
+
if sid = current_session_id(env)
|
|
61
|
+
get_session_model(env, sid).destroy
|
|
62
|
+
env[SESSION_RECORD_KEY] = nil
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def pack(data)
|
|
67
|
+
Marshal.dump(data)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def unpack(packed)
|
|
71
|
+
return nil unless packed
|
|
72
|
+
Marshal.load(StringIO.new(packed.to_s))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'mongoid'
|
|
3
|
+
require 'mongo_session_store/mongo_store_base'
|
|
4
|
+
|
|
5
|
+
module ActionDispatch
|
|
6
|
+
module Session
|
|
7
|
+
class MongoidStore < MongoStoreBase
|
|
8
|
+
|
|
9
|
+
class Session
|
|
10
|
+
include Mongoid::Document
|
|
11
|
+
include Mongoid::Timestamps
|
|
12
|
+
self.collection_name = MongoSessionStore.collection_name
|
|
13
|
+
|
|
14
|
+
identity :type => String
|
|
15
|
+
|
|
16
|
+
field :data, :type => BSON::Binary, :default => BSON::Binary.new(Marshal.dump({}))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
def pack(data)
|
|
21
|
+
BSON::Binary.new(Marshal.dump(data))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def unpack(packed)
|
|
25
|
+
return nil unless packed
|
|
26
|
+
Marshal.load(StringIO.new(packed.to_s))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
rescue LoadError
|
|
34
|
+
end
|